summaryrefslogtreecommitdiff
path: root/libjava/gnu/gcj/natCore.cc
blob: 2d650f7101dbbe0c28d5cb7f3d7170971b520807 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// natCore -- C++ side of Core

/* Copyright (C) 2001, 2002, 2003, 2005, 2006  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

/* Author: Anthony Green <green@redhat.com>.  */

#include <config.h>

#include <gcj/cni.h>
#include <jvm.h>
#include <string.h>
#include <stdlib.h>

#include <java/lang/NullPointerException.h>
#include <java/io/IOException.h>
#include <gnu/gcj/Core.h>

// List of global core values.
static _Jv_core_chain *root;

static void
default_register_resource (_Jv_core_chain *node)
{
  node->next = root;
  root = node;
}

// This is set only when a lock is held on java.lang.Class.
// This function is called to handle a new core node.
void (*_Jv_RegisterCoreHook) (_Jv_core_chain *) = default_register_resource;

void
_Jv_RegisterResource (void *vptr)
{
  char *rptr = (char *) vptr;

  _Jv_core_chain *cc = (_Jv_core_chain *) _Jv_Malloc (sizeof (_Jv_core_chain));

  cc->name_length = ((int *)rptr)[0];
  cc->data_length = ((int *)rptr)[1];
  cc->name = rptr + 2 * sizeof (int);
  cc->data = cc->name + cc->name_length;
  cc->next = NULL;

  (*_Jv_RegisterCoreHook) (cc);
}

void
_Jv_FreeCoreChain (_Jv_core_chain *chain)
{
  while (chain != NULL)
    {
      _Jv_core_chain *next = chain->next;
      _Jv_Free (chain);
      chain = next;
    }
}

_Jv_core_chain *
_Jv_FindCore (_Jv_core_chain *node, jstring name)
{
  char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (name) + 1);
  jsize total = JvGetStringUTFRegion (name, 0, name->length(), buf);
  buf[total] = '\0';

  // Usually requests here end up as an absolute URL.  We strip the
  // initial `/'.
  if (buf[0] == '/')
    {
      ++buf;
      --total;
    }

  while (node)
    {
      if (total == node->name_length
	  && strncmp (buf, node->name, total) == 0)
	return node;
      node = node->next;
    }

  return NULL;
}

gnu::gcj::Core *
_Jv_create_core (_Jv_core_chain *node, jstring name)
{
  node = _Jv_FindCore (node, name);

  gnu::gcj::Core *core = NULL;
  if (node)
    {
      core = new gnu::gcj::Core ();
      core->ptr = (gnu::gcj::RawData *) node->data;
      core->length = node->data_length;
    }
  return core;
}

gnu::gcj::Core *
gnu::gcj::Core::find (jstring name)
{
  gnu::gcj::Core *core = _Jv_create_core (root, name);
  return core;
}

gnu::gcj::Core *
gnu::gcj::Core::create (jstring name)
{
  gnu::gcj::Core *core = _Jv_create_core (root, name);
  if (core == NULL)
    throw new ::java::io::IOException (JvNewStringLatin1 ("can't open core"));
  return core;
}