1*e82f7db8SAndroid Build Coastguard Worker /*
2*e82f7db8SAndroid Build Coastguard Worker * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
3*e82f7db8SAndroid Build Coastguard Worker * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*e82f7db8SAndroid Build Coastguard Worker *
5*e82f7db8SAndroid Build Coastguard Worker * This code is free software; you can redistribute it and/or modify it
6*e82f7db8SAndroid Build Coastguard Worker * under the terms of the GNU General Public License version 2 only, as
7*e82f7db8SAndroid Build Coastguard Worker * published by the Free Software Foundation. Oracle designates this
8*e82f7db8SAndroid Build Coastguard Worker * particular file as subject to the "Classpath" exception as provided
9*e82f7db8SAndroid Build Coastguard Worker * by Oracle in the LICENSE file that accompanied this code.
10*e82f7db8SAndroid Build Coastguard Worker *
11*e82f7db8SAndroid Build Coastguard Worker * This code is distributed in the hope that it will be useful, but WITHOUT
12*e82f7db8SAndroid Build Coastguard Worker * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*e82f7db8SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14*e82f7db8SAndroid Build Coastguard Worker * version 2 for more details (a copy is included in the LICENSE file that
15*e82f7db8SAndroid Build Coastguard Worker * accompanied this code).
16*e82f7db8SAndroid Build Coastguard Worker *
17*e82f7db8SAndroid Build Coastguard Worker * You should have received a copy of the GNU General Public License version
18*e82f7db8SAndroid Build Coastguard Worker * 2 along with this work; if not, write to the Free Software Foundation,
19*e82f7db8SAndroid Build Coastguard Worker * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20*e82f7db8SAndroid Build Coastguard Worker *
21*e82f7db8SAndroid Build Coastguard Worker * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22*e82f7db8SAndroid Build Coastguard Worker * or visit www.oracle.com if you need additional information or have any
23*e82f7db8SAndroid Build Coastguard Worker * questions.
24*e82f7db8SAndroid Build Coastguard Worker */
25*e82f7db8SAndroid Build Coastguard Worker
26*e82f7db8SAndroid Build Coastguard Worker #include "util.h"
27*e82f7db8SAndroid Build Coastguard Worker #include "stream.h"
28*e82f7db8SAndroid Build Coastguard Worker #include "inStream.h"
29*e82f7db8SAndroid Build Coastguard Worker #include "transport.h"
30*e82f7db8SAndroid Build Coastguard Worker #include "bag.h"
31*e82f7db8SAndroid Build Coastguard Worker #include "commonRef.h"
32*e82f7db8SAndroid Build Coastguard Worker #include "FrameID.h"
33*e82f7db8SAndroid Build Coastguard Worker
34*e82f7db8SAndroid Build Coastguard Worker #define INITIAL_REF_ALLOC 50
35*e82f7db8SAndroid Build Coastguard Worker #define SMALLEST(a, b) ((a) < (b)) ? (a) : (b)
36*e82f7db8SAndroid Build Coastguard Worker
37*e82f7db8SAndroid Build Coastguard Worker /*
38*e82f7db8SAndroid Build Coastguard Worker * TO DO: Support processing of replies through command input streams.
39*e82f7db8SAndroid Build Coastguard Worker */
40*e82f7db8SAndroid Build Coastguard Worker void
inStream_init(PacketInputStream * stream,jdwpPacket packet)41*e82f7db8SAndroid Build Coastguard Worker inStream_init(PacketInputStream *stream, jdwpPacket packet)
42*e82f7db8SAndroid Build Coastguard Worker {
43*e82f7db8SAndroid Build Coastguard Worker stream->packet = packet;
44*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(NONE);
45*e82f7db8SAndroid Build Coastguard Worker stream->left = packet.type.cmd.len;
46*e82f7db8SAndroid Build Coastguard Worker stream->current = packet.type.cmd.data;
47*e82f7db8SAndroid Build Coastguard Worker stream->refs = bagCreateBag(sizeof(jobject), INITIAL_REF_ALLOC);
48*e82f7db8SAndroid Build Coastguard Worker if (stream->refs == NULL) {
49*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(OUT_OF_MEMORY);
50*e82f7db8SAndroid Build Coastguard Worker }
51*e82f7db8SAndroid Build Coastguard Worker }
52*e82f7db8SAndroid Build Coastguard Worker
53*e82f7db8SAndroid Build Coastguard Worker jint
inStream_id(PacketInputStream * stream)54*e82f7db8SAndroid Build Coastguard Worker inStream_id(PacketInputStream *stream)
55*e82f7db8SAndroid Build Coastguard Worker {
56*e82f7db8SAndroid Build Coastguard Worker return stream->packet.type.cmd.id;
57*e82f7db8SAndroid Build Coastguard Worker }
58*e82f7db8SAndroid Build Coastguard Worker
59*e82f7db8SAndroid Build Coastguard Worker jbyte
inStream_command(PacketInputStream * stream)60*e82f7db8SAndroid Build Coastguard Worker inStream_command(PacketInputStream *stream)
61*e82f7db8SAndroid Build Coastguard Worker {
62*e82f7db8SAndroid Build Coastguard Worker return stream->packet.type.cmd.cmd;
63*e82f7db8SAndroid Build Coastguard Worker }
64*e82f7db8SAndroid Build Coastguard Worker
65*e82f7db8SAndroid Build Coastguard Worker static jdwpError
readBytes(PacketInputStream * stream,void * dest,int size)66*e82f7db8SAndroid Build Coastguard Worker readBytes(PacketInputStream *stream, void *dest, int size)
67*e82f7db8SAndroid Build Coastguard Worker {
68*e82f7db8SAndroid Build Coastguard Worker if (stream->error) {
69*e82f7db8SAndroid Build Coastguard Worker return stream->error;
70*e82f7db8SAndroid Build Coastguard Worker }
71*e82f7db8SAndroid Build Coastguard Worker
72*e82f7db8SAndroid Build Coastguard Worker if (size > stream->left) {
73*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(INTERNAL);
74*e82f7db8SAndroid Build Coastguard Worker return stream->error;
75*e82f7db8SAndroid Build Coastguard Worker }
76*e82f7db8SAndroid Build Coastguard Worker
77*e82f7db8SAndroid Build Coastguard Worker if (dest) {
78*e82f7db8SAndroid Build Coastguard Worker (void)memcpy(dest, stream->current, size);
79*e82f7db8SAndroid Build Coastguard Worker }
80*e82f7db8SAndroid Build Coastguard Worker stream->current += size;
81*e82f7db8SAndroid Build Coastguard Worker stream->left -= size;
82*e82f7db8SAndroid Build Coastguard Worker
83*e82f7db8SAndroid Build Coastguard Worker return stream->error;
84*e82f7db8SAndroid Build Coastguard Worker }
85*e82f7db8SAndroid Build Coastguard Worker
86*e82f7db8SAndroid Build Coastguard Worker jdwpError
inStream_skipBytes(PacketInputStream * stream,jint size)87*e82f7db8SAndroid Build Coastguard Worker inStream_skipBytes(PacketInputStream *stream, jint size) {
88*e82f7db8SAndroid Build Coastguard Worker return readBytes(stream, NULL, size);
89*e82f7db8SAndroid Build Coastguard Worker }
90*e82f7db8SAndroid Build Coastguard Worker
91*e82f7db8SAndroid Build Coastguard Worker jboolean
inStream_readBoolean(PacketInputStream * stream)92*e82f7db8SAndroid Build Coastguard Worker inStream_readBoolean(PacketInputStream *stream)
93*e82f7db8SAndroid Build Coastguard Worker {
94*e82f7db8SAndroid Build Coastguard Worker jbyte flag = 0;
95*e82f7db8SAndroid Build Coastguard Worker (void)readBytes(stream, &flag, sizeof(flag));
96*e82f7db8SAndroid Build Coastguard Worker if (stream->error) {
97*e82f7db8SAndroid Build Coastguard Worker return 0;
98*e82f7db8SAndroid Build Coastguard Worker } else {
99*e82f7db8SAndroid Build Coastguard Worker return flag ? JNI_TRUE : JNI_FALSE;
100*e82f7db8SAndroid Build Coastguard Worker }
101*e82f7db8SAndroid Build Coastguard Worker }
102*e82f7db8SAndroid Build Coastguard Worker
103*e82f7db8SAndroid Build Coastguard Worker jbyte
inStream_readByte(PacketInputStream * stream)104*e82f7db8SAndroid Build Coastguard Worker inStream_readByte(PacketInputStream *stream)
105*e82f7db8SAndroid Build Coastguard Worker {
106*e82f7db8SAndroid Build Coastguard Worker jbyte val = 0;
107*e82f7db8SAndroid Build Coastguard Worker (void)readBytes(stream, &val, sizeof(val));
108*e82f7db8SAndroid Build Coastguard Worker return val;
109*e82f7db8SAndroid Build Coastguard Worker }
110*e82f7db8SAndroid Build Coastguard Worker
111*e82f7db8SAndroid Build Coastguard Worker jbyte *
inStream_readBytes(PacketInputStream * stream,int length,jbyte * buf)112*e82f7db8SAndroid Build Coastguard Worker inStream_readBytes(PacketInputStream *stream, int length, jbyte *buf)
113*e82f7db8SAndroid Build Coastguard Worker {
114*e82f7db8SAndroid Build Coastguard Worker (void)readBytes(stream, buf, length);
115*e82f7db8SAndroid Build Coastguard Worker return buf;
116*e82f7db8SAndroid Build Coastguard Worker }
117*e82f7db8SAndroid Build Coastguard Worker
118*e82f7db8SAndroid Build Coastguard Worker jchar
inStream_readChar(PacketInputStream * stream)119*e82f7db8SAndroid Build Coastguard Worker inStream_readChar(PacketInputStream *stream)
120*e82f7db8SAndroid Build Coastguard Worker {
121*e82f7db8SAndroid Build Coastguard Worker jchar val = 0;
122*e82f7db8SAndroid Build Coastguard Worker (void)readBytes(stream, &val, sizeof(val));
123*e82f7db8SAndroid Build Coastguard Worker return JAVA_TO_HOST_CHAR(val);
124*e82f7db8SAndroid Build Coastguard Worker }
125*e82f7db8SAndroid Build Coastguard Worker
126*e82f7db8SAndroid Build Coastguard Worker jshort
inStream_readShort(PacketInputStream * stream)127*e82f7db8SAndroid Build Coastguard Worker inStream_readShort(PacketInputStream *stream)
128*e82f7db8SAndroid Build Coastguard Worker {
129*e82f7db8SAndroid Build Coastguard Worker jshort val = 0;
130*e82f7db8SAndroid Build Coastguard Worker (void)readBytes(stream, &val, sizeof(val));
131*e82f7db8SAndroid Build Coastguard Worker return JAVA_TO_HOST_SHORT(val);
132*e82f7db8SAndroid Build Coastguard Worker }
133*e82f7db8SAndroid Build Coastguard Worker
134*e82f7db8SAndroid Build Coastguard Worker jint
inStream_readInt(PacketInputStream * stream)135*e82f7db8SAndroid Build Coastguard Worker inStream_readInt(PacketInputStream *stream)
136*e82f7db8SAndroid Build Coastguard Worker {
137*e82f7db8SAndroid Build Coastguard Worker jint val = 0;
138*e82f7db8SAndroid Build Coastguard Worker (void)readBytes(stream, &val, sizeof(val));
139*e82f7db8SAndroid Build Coastguard Worker return JAVA_TO_HOST_INT(val);
140*e82f7db8SAndroid Build Coastguard Worker }
141*e82f7db8SAndroid Build Coastguard Worker
142*e82f7db8SAndroid Build Coastguard Worker jlong
inStream_readLong(PacketInputStream * stream)143*e82f7db8SAndroid Build Coastguard Worker inStream_readLong(PacketInputStream *stream)
144*e82f7db8SAndroid Build Coastguard Worker {
145*e82f7db8SAndroid Build Coastguard Worker jlong val = 0;
146*e82f7db8SAndroid Build Coastguard Worker (void)readBytes(stream, &val, sizeof(val));
147*e82f7db8SAndroid Build Coastguard Worker return JAVA_TO_HOST_LONG(val);
148*e82f7db8SAndroid Build Coastguard Worker }
149*e82f7db8SAndroid Build Coastguard Worker
150*e82f7db8SAndroid Build Coastguard Worker jfloat
inStream_readFloat(PacketInputStream * stream)151*e82f7db8SAndroid Build Coastguard Worker inStream_readFloat(PacketInputStream *stream)
152*e82f7db8SAndroid Build Coastguard Worker {
153*e82f7db8SAndroid Build Coastguard Worker jfloat val = 0;
154*e82f7db8SAndroid Build Coastguard Worker (void)readBytes(stream, &val, sizeof(val));
155*e82f7db8SAndroid Build Coastguard Worker return JAVA_TO_HOST_FLOAT(val);
156*e82f7db8SAndroid Build Coastguard Worker }
157*e82f7db8SAndroid Build Coastguard Worker
158*e82f7db8SAndroid Build Coastguard Worker jdouble
inStream_readDouble(PacketInputStream * stream)159*e82f7db8SAndroid Build Coastguard Worker inStream_readDouble(PacketInputStream *stream)
160*e82f7db8SAndroid Build Coastguard Worker {
161*e82f7db8SAndroid Build Coastguard Worker jdouble val = 0;
162*e82f7db8SAndroid Build Coastguard Worker (void)readBytes(stream, &val, sizeof(val));
163*e82f7db8SAndroid Build Coastguard Worker return JAVA_TO_HOST_DOUBLE(val);
164*e82f7db8SAndroid Build Coastguard Worker }
165*e82f7db8SAndroid Build Coastguard Worker
166*e82f7db8SAndroid Build Coastguard Worker /*
167*e82f7db8SAndroid Build Coastguard Worker * Read an object from the stream. The ID used in the wire protocol
168*e82f7db8SAndroid Build Coastguard Worker * is converted to a reference which is returned. The reference is
169*e82f7db8SAndroid Build Coastguard Worker * global and strong, but it should *not* be deleted by the caller
170*e82f7db8SAndroid Build Coastguard Worker * since it is freed when this stream is destroyed.
171*e82f7db8SAndroid Build Coastguard Worker */
172*e82f7db8SAndroid Build Coastguard Worker jobject
inStream_readObjectRef(JNIEnv * env,PacketInputStream * stream)173*e82f7db8SAndroid Build Coastguard Worker inStream_readObjectRef(JNIEnv *env, PacketInputStream *stream)
174*e82f7db8SAndroid Build Coastguard Worker {
175*e82f7db8SAndroid Build Coastguard Worker jobject ref;
176*e82f7db8SAndroid Build Coastguard Worker jobject *refPtr;
177*e82f7db8SAndroid Build Coastguard Worker jlong id = inStream_readLong(stream);
178*e82f7db8SAndroid Build Coastguard Worker if (stream->error) {
179*e82f7db8SAndroid Build Coastguard Worker return NULL;
180*e82f7db8SAndroid Build Coastguard Worker }
181*e82f7db8SAndroid Build Coastguard Worker if (id == NULL_OBJECT_ID) {
182*e82f7db8SAndroid Build Coastguard Worker return NULL;
183*e82f7db8SAndroid Build Coastguard Worker }
184*e82f7db8SAndroid Build Coastguard Worker
185*e82f7db8SAndroid Build Coastguard Worker ref = commonRef_idToRef(env, id);
186*e82f7db8SAndroid Build Coastguard Worker if (ref == NULL) {
187*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(INVALID_OBJECT);
188*e82f7db8SAndroid Build Coastguard Worker return NULL;
189*e82f7db8SAndroid Build Coastguard Worker }
190*e82f7db8SAndroid Build Coastguard Worker
191*e82f7db8SAndroid Build Coastguard Worker refPtr = bagAdd(stream->refs);
192*e82f7db8SAndroid Build Coastguard Worker if (refPtr == NULL) {
193*e82f7db8SAndroid Build Coastguard Worker commonRef_idToRef_delete(env, ref);
194*e82f7db8SAndroid Build Coastguard Worker return NULL;
195*e82f7db8SAndroid Build Coastguard Worker }
196*e82f7db8SAndroid Build Coastguard Worker
197*e82f7db8SAndroid Build Coastguard Worker *refPtr = ref;
198*e82f7db8SAndroid Build Coastguard Worker return ref;
199*e82f7db8SAndroid Build Coastguard Worker }
200*e82f7db8SAndroid Build Coastguard Worker
201*e82f7db8SAndroid Build Coastguard Worker /*
202*e82f7db8SAndroid Build Coastguard Worker * Read a raw object id from the stream. This should be used rarely.
203*e82f7db8SAndroid Build Coastguard Worker * Normally, inStream_readObjectRef is preferred since it takes care
204*e82f7db8SAndroid Build Coastguard Worker * of reference conversion and tracking. Only code that needs to
205*e82f7db8SAndroid Build Coastguard Worker * perform maintence of the commonRef hash table uses this function.
206*e82f7db8SAndroid Build Coastguard Worker */
207*e82f7db8SAndroid Build Coastguard Worker jlong
inStream_readObjectID(PacketInputStream * stream)208*e82f7db8SAndroid Build Coastguard Worker inStream_readObjectID(PacketInputStream *stream)
209*e82f7db8SAndroid Build Coastguard Worker {
210*e82f7db8SAndroid Build Coastguard Worker return inStream_readLong(stream);
211*e82f7db8SAndroid Build Coastguard Worker }
212*e82f7db8SAndroid Build Coastguard Worker
213*e82f7db8SAndroid Build Coastguard Worker jclass
inStream_readClassRef(JNIEnv * env,PacketInputStream * stream)214*e82f7db8SAndroid Build Coastguard Worker inStream_readClassRef(JNIEnv *env, PacketInputStream *stream)
215*e82f7db8SAndroid Build Coastguard Worker {
216*e82f7db8SAndroid Build Coastguard Worker jobject object = inStream_readObjectRef(env, stream);
217*e82f7db8SAndroid Build Coastguard Worker if (object == NULL) {
218*e82f7db8SAndroid Build Coastguard Worker /*
219*e82f7db8SAndroid Build Coastguard Worker * Could be error or just the null reference. In either case,
220*e82f7db8SAndroid Build Coastguard Worker * stop now.
221*e82f7db8SAndroid Build Coastguard Worker */
222*e82f7db8SAndroid Build Coastguard Worker return NULL;
223*e82f7db8SAndroid Build Coastguard Worker }
224*e82f7db8SAndroid Build Coastguard Worker if (!isClass(object)) {
225*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(INVALID_CLASS);
226*e82f7db8SAndroid Build Coastguard Worker return NULL;
227*e82f7db8SAndroid Build Coastguard Worker }
228*e82f7db8SAndroid Build Coastguard Worker return object;
229*e82f7db8SAndroid Build Coastguard Worker }
230*e82f7db8SAndroid Build Coastguard Worker
231*e82f7db8SAndroid Build Coastguard Worker jthread
inStream_readThreadRef(JNIEnv * env,PacketInputStream * stream)232*e82f7db8SAndroid Build Coastguard Worker inStream_readThreadRef(JNIEnv *env, PacketInputStream *stream)
233*e82f7db8SAndroid Build Coastguard Worker {
234*e82f7db8SAndroid Build Coastguard Worker jobject object = inStream_readObjectRef(env, stream);
235*e82f7db8SAndroid Build Coastguard Worker if (object == NULL) {
236*e82f7db8SAndroid Build Coastguard Worker /*
237*e82f7db8SAndroid Build Coastguard Worker * Could be error or just the null reference. In either case,
238*e82f7db8SAndroid Build Coastguard Worker * stop now.
239*e82f7db8SAndroid Build Coastguard Worker */
240*e82f7db8SAndroid Build Coastguard Worker return NULL;
241*e82f7db8SAndroid Build Coastguard Worker }
242*e82f7db8SAndroid Build Coastguard Worker if (!isThread(object)) {
243*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(INVALID_THREAD);
244*e82f7db8SAndroid Build Coastguard Worker return NULL;
245*e82f7db8SAndroid Build Coastguard Worker }
246*e82f7db8SAndroid Build Coastguard Worker return object;
247*e82f7db8SAndroid Build Coastguard Worker }
248*e82f7db8SAndroid Build Coastguard Worker
249*e82f7db8SAndroid Build Coastguard Worker jthreadGroup
inStream_readThreadGroupRef(JNIEnv * env,PacketInputStream * stream)250*e82f7db8SAndroid Build Coastguard Worker inStream_readThreadGroupRef(JNIEnv *env, PacketInputStream *stream)
251*e82f7db8SAndroid Build Coastguard Worker {
252*e82f7db8SAndroid Build Coastguard Worker jobject object = inStream_readObjectRef(env, stream);
253*e82f7db8SAndroid Build Coastguard Worker if (object == NULL) {
254*e82f7db8SAndroid Build Coastguard Worker /*
255*e82f7db8SAndroid Build Coastguard Worker * Could be error or just the null reference. In either case,
256*e82f7db8SAndroid Build Coastguard Worker * stop now.
257*e82f7db8SAndroid Build Coastguard Worker */
258*e82f7db8SAndroid Build Coastguard Worker return NULL;
259*e82f7db8SAndroid Build Coastguard Worker }
260*e82f7db8SAndroid Build Coastguard Worker if (!isThreadGroup(object)) {
261*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(INVALID_THREAD_GROUP);
262*e82f7db8SAndroid Build Coastguard Worker return NULL;
263*e82f7db8SAndroid Build Coastguard Worker }
264*e82f7db8SAndroid Build Coastguard Worker return object;
265*e82f7db8SAndroid Build Coastguard Worker }
266*e82f7db8SAndroid Build Coastguard Worker
267*e82f7db8SAndroid Build Coastguard Worker jstring
inStream_readStringRef(JNIEnv * env,PacketInputStream * stream)268*e82f7db8SAndroid Build Coastguard Worker inStream_readStringRef(JNIEnv *env, PacketInputStream *stream)
269*e82f7db8SAndroid Build Coastguard Worker {
270*e82f7db8SAndroid Build Coastguard Worker jobject object = inStream_readObjectRef(env, stream);
271*e82f7db8SAndroid Build Coastguard Worker if (object == NULL) {
272*e82f7db8SAndroid Build Coastguard Worker /*
273*e82f7db8SAndroid Build Coastguard Worker * Could be error or just the null reference. In either case,
274*e82f7db8SAndroid Build Coastguard Worker * stop now.
275*e82f7db8SAndroid Build Coastguard Worker */
276*e82f7db8SAndroid Build Coastguard Worker return NULL;
277*e82f7db8SAndroid Build Coastguard Worker }
278*e82f7db8SAndroid Build Coastguard Worker if (!isString(object)) {
279*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(INVALID_STRING);
280*e82f7db8SAndroid Build Coastguard Worker return NULL;
281*e82f7db8SAndroid Build Coastguard Worker }
282*e82f7db8SAndroid Build Coastguard Worker return object;
283*e82f7db8SAndroid Build Coastguard Worker }
284*e82f7db8SAndroid Build Coastguard Worker
285*e82f7db8SAndroid Build Coastguard Worker jclass
inStream_readClassLoaderRef(JNIEnv * env,PacketInputStream * stream)286*e82f7db8SAndroid Build Coastguard Worker inStream_readClassLoaderRef(JNIEnv *env, PacketInputStream *stream)
287*e82f7db8SAndroid Build Coastguard Worker {
288*e82f7db8SAndroid Build Coastguard Worker jobject object = inStream_readObjectRef(env, stream);
289*e82f7db8SAndroid Build Coastguard Worker if (object == NULL) {
290*e82f7db8SAndroid Build Coastguard Worker /*
291*e82f7db8SAndroid Build Coastguard Worker * Could be error or just the null reference. In either case,
292*e82f7db8SAndroid Build Coastguard Worker * stop now.
293*e82f7db8SAndroid Build Coastguard Worker */
294*e82f7db8SAndroid Build Coastguard Worker return NULL;
295*e82f7db8SAndroid Build Coastguard Worker }
296*e82f7db8SAndroid Build Coastguard Worker if (!isClassLoader(object)) {
297*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(INVALID_CLASS_LOADER);
298*e82f7db8SAndroid Build Coastguard Worker return NULL;
299*e82f7db8SAndroid Build Coastguard Worker }
300*e82f7db8SAndroid Build Coastguard Worker return object;
301*e82f7db8SAndroid Build Coastguard Worker }
302*e82f7db8SAndroid Build Coastguard Worker
303*e82f7db8SAndroid Build Coastguard Worker jarray
inStream_readArrayRef(JNIEnv * env,PacketInputStream * stream)304*e82f7db8SAndroid Build Coastguard Worker inStream_readArrayRef(JNIEnv *env, PacketInputStream *stream)
305*e82f7db8SAndroid Build Coastguard Worker {
306*e82f7db8SAndroid Build Coastguard Worker jobject object = inStream_readObjectRef(env, stream);
307*e82f7db8SAndroid Build Coastguard Worker if (object == NULL) {
308*e82f7db8SAndroid Build Coastguard Worker /*
309*e82f7db8SAndroid Build Coastguard Worker * Could be error or just the null reference. In either case,
310*e82f7db8SAndroid Build Coastguard Worker * stop now.
311*e82f7db8SAndroid Build Coastguard Worker */
312*e82f7db8SAndroid Build Coastguard Worker return NULL;
313*e82f7db8SAndroid Build Coastguard Worker }
314*e82f7db8SAndroid Build Coastguard Worker if (!isArray(object)) {
315*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(INVALID_ARRAY);
316*e82f7db8SAndroid Build Coastguard Worker return NULL;
317*e82f7db8SAndroid Build Coastguard Worker }
318*e82f7db8SAndroid Build Coastguard Worker return object;
319*e82f7db8SAndroid Build Coastguard Worker }
320*e82f7db8SAndroid Build Coastguard Worker
321*e82f7db8SAndroid Build Coastguard Worker /*
322*e82f7db8SAndroid Build Coastguard Worker * Next 3 functions read an Int and convert to a Pointer!?
323*e82f7db8SAndroid Build Coastguard Worker * If sizeof(jxxxID) == 8 we must read these values as Longs.
324*e82f7db8SAndroid Build Coastguard Worker */
325*e82f7db8SAndroid Build Coastguard Worker FrameID
inStream_readFrameID(PacketInputStream * stream)326*e82f7db8SAndroid Build Coastguard Worker inStream_readFrameID(PacketInputStream *stream)
327*e82f7db8SAndroid Build Coastguard Worker {
328*e82f7db8SAndroid Build Coastguard Worker if (sizeof(FrameID) == 8) {
329*e82f7db8SAndroid Build Coastguard Worker /*LINTED*/
330*e82f7db8SAndroid Build Coastguard Worker return (FrameID)inStream_readLong(stream);
331*e82f7db8SAndroid Build Coastguard Worker } else {
332*e82f7db8SAndroid Build Coastguard Worker /*LINTED*/
333*e82f7db8SAndroid Build Coastguard Worker return (FrameID)inStream_readInt(stream);
334*e82f7db8SAndroid Build Coastguard Worker }
335*e82f7db8SAndroid Build Coastguard Worker }
336*e82f7db8SAndroid Build Coastguard Worker
337*e82f7db8SAndroid Build Coastguard Worker jmethodID
inStream_readMethodID(PacketInputStream * stream)338*e82f7db8SAndroid Build Coastguard Worker inStream_readMethodID(PacketInputStream *stream)
339*e82f7db8SAndroid Build Coastguard Worker {
340*e82f7db8SAndroid Build Coastguard Worker if (sizeof(jmethodID) == 8) {
341*e82f7db8SAndroid Build Coastguard Worker /*LINTED*/
342*e82f7db8SAndroid Build Coastguard Worker return (jmethodID)(intptr_t)inStream_readLong(stream);
343*e82f7db8SAndroid Build Coastguard Worker } else {
344*e82f7db8SAndroid Build Coastguard Worker /*LINTED*/
345*e82f7db8SAndroid Build Coastguard Worker return (jmethodID)(intptr_t)inStream_readInt(stream);
346*e82f7db8SAndroid Build Coastguard Worker }
347*e82f7db8SAndroid Build Coastguard Worker }
348*e82f7db8SAndroid Build Coastguard Worker
349*e82f7db8SAndroid Build Coastguard Worker jfieldID
inStream_readFieldID(PacketInputStream * stream)350*e82f7db8SAndroid Build Coastguard Worker inStream_readFieldID(PacketInputStream *stream)
351*e82f7db8SAndroid Build Coastguard Worker {
352*e82f7db8SAndroid Build Coastguard Worker if (sizeof(jfieldID) == 8) {
353*e82f7db8SAndroid Build Coastguard Worker /*LINTED*/
354*e82f7db8SAndroid Build Coastguard Worker return (jfieldID)(intptr_t)inStream_readLong(stream);
355*e82f7db8SAndroid Build Coastguard Worker } else {
356*e82f7db8SAndroid Build Coastguard Worker /*LINTED*/
357*e82f7db8SAndroid Build Coastguard Worker return (jfieldID)(intptr_t)inStream_readInt(stream);
358*e82f7db8SAndroid Build Coastguard Worker }
359*e82f7db8SAndroid Build Coastguard Worker }
360*e82f7db8SAndroid Build Coastguard Worker
361*e82f7db8SAndroid Build Coastguard Worker jlocation
inStream_readLocation(PacketInputStream * stream)362*e82f7db8SAndroid Build Coastguard Worker inStream_readLocation(PacketInputStream *stream)
363*e82f7db8SAndroid Build Coastguard Worker {
364*e82f7db8SAndroid Build Coastguard Worker return (jlocation)inStream_readLong(stream);
365*e82f7db8SAndroid Build Coastguard Worker }
366*e82f7db8SAndroid Build Coastguard Worker
367*e82f7db8SAndroid Build Coastguard Worker char *
inStream_readString(PacketInputStream * stream)368*e82f7db8SAndroid Build Coastguard Worker inStream_readString(PacketInputStream *stream)
369*e82f7db8SAndroid Build Coastguard Worker {
370*e82f7db8SAndroid Build Coastguard Worker int length;
371*e82f7db8SAndroid Build Coastguard Worker char *string;
372*e82f7db8SAndroid Build Coastguard Worker
373*e82f7db8SAndroid Build Coastguard Worker length = inStream_readInt(stream);
374*e82f7db8SAndroid Build Coastguard Worker string = jvmtiAllocate(length + 1);
375*e82f7db8SAndroid Build Coastguard Worker if (string != NULL) {
376*e82f7db8SAndroid Build Coastguard Worker int new_length;
377*e82f7db8SAndroid Build Coastguard Worker
378*e82f7db8SAndroid Build Coastguard Worker (void)readBytes(stream, string, length);
379*e82f7db8SAndroid Build Coastguard Worker string[length] = '\0';
380*e82f7db8SAndroid Build Coastguard Worker
381*e82f7db8SAndroid Build Coastguard Worker /* This is Standard UTF-8, convert to Modified UTF-8 if necessary */
382*e82f7db8SAndroid Build Coastguard Worker new_length = (gdata->npt->utf8sToUtf8mLength)
383*e82f7db8SAndroid Build Coastguard Worker (gdata->npt->utf, (jbyte*)string, length);
384*e82f7db8SAndroid Build Coastguard Worker if ( new_length != length ) {
385*e82f7db8SAndroid Build Coastguard Worker char *new_string;
386*e82f7db8SAndroid Build Coastguard Worker
387*e82f7db8SAndroid Build Coastguard Worker new_string = jvmtiAllocate(new_length+1);
388*e82f7db8SAndroid Build Coastguard Worker (gdata->npt->utf8sToUtf8m)
389*e82f7db8SAndroid Build Coastguard Worker (gdata->npt->utf, (jbyte*)string, length,
390*e82f7db8SAndroid Build Coastguard Worker (jbyte*)new_string, new_length);
391*e82f7db8SAndroid Build Coastguard Worker jvmtiDeallocate(string);
392*e82f7db8SAndroid Build Coastguard Worker return new_string;
393*e82f7db8SAndroid Build Coastguard Worker }
394*e82f7db8SAndroid Build Coastguard Worker }
395*e82f7db8SAndroid Build Coastguard Worker return string;
396*e82f7db8SAndroid Build Coastguard Worker }
397*e82f7db8SAndroid Build Coastguard Worker
398*e82f7db8SAndroid Build Coastguard Worker jboolean
inStream_endOfInput(PacketInputStream * stream)399*e82f7db8SAndroid Build Coastguard Worker inStream_endOfInput(PacketInputStream *stream)
400*e82f7db8SAndroid Build Coastguard Worker {
401*e82f7db8SAndroid Build Coastguard Worker return (stream->left > 0);
402*e82f7db8SAndroid Build Coastguard Worker }
403*e82f7db8SAndroid Build Coastguard Worker
404*e82f7db8SAndroid Build Coastguard Worker jdwpError
inStream_error(PacketInputStream * stream)405*e82f7db8SAndroid Build Coastguard Worker inStream_error(PacketInputStream *stream)
406*e82f7db8SAndroid Build Coastguard Worker {
407*e82f7db8SAndroid Build Coastguard Worker return stream->error;
408*e82f7db8SAndroid Build Coastguard Worker }
409*e82f7db8SAndroid Build Coastguard Worker
410*e82f7db8SAndroid Build Coastguard Worker void
inStream_clearError(PacketInputStream * stream)411*e82f7db8SAndroid Build Coastguard Worker inStream_clearError(PacketInputStream *stream) {
412*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(NONE);
413*e82f7db8SAndroid Build Coastguard Worker }
414*e82f7db8SAndroid Build Coastguard Worker
415*e82f7db8SAndroid Build Coastguard Worker jvalue
inStream_readValue(PacketInputStream * stream,jbyte * typeKeyPtr)416*e82f7db8SAndroid Build Coastguard Worker inStream_readValue(PacketInputStream *stream, jbyte *typeKeyPtr)
417*e82f7db8SAndroid Build Coastguard Worker {
418*e82f7db8SAndroid Build Coastguard Worker jvalue value;
419*e82f7db8SAndroid Build Coastguard Worker jbyte typeKey = inStream_readByte(stream);
420*e82f7db8SAndroid Build Coastguard Worker if (stream->error) {
421*e82f7db8SAndroid Build Coastguard Worker value.j = 0L;
422*e82f7db8SAndroid Build Coastguard Worker return value;
423*e82f7db8SAndroid Build Coastguard Worker }
424*e82f7db8SAndroid Build Coastguard Worker
425*e82f7db8SAndroid Build Coastguard Worker if (isObjectTag(typeKey)) {
426*e82f7db8SAndroid Build Coastguard Worker value.l = inStream_readObjectRef(getEnv(), stream);
427*e82f7db8SAndroid Build Coastguard Worker } else {
428*e82f7db8SAndroid Build Coastguard Worker switch (typeKey) {
429*e82f7db8SAndroid Build Coastguard Worker case JDWP_TAG(BYTE):
430*e82f7db8SAndroid Build Coastguard Worker value.b = inStream_readByte(stream);
431*e82f7db8SAndroid Build Coastguard Worker break;
432*e82f7db8SAndroid Build Coastguard Worker
433*e82f7db8SAndroid Build Coastguard Worker case JDWP_TAG(CHAR):
434*e82f7db8SAndroid Build Coastguard Worker value.c = inStream_readChar(stream);
435*e82f7db8SAndroid Build Coastguard Worker break;
436*e82f7db8SAndroid Build Coastguard Worker
437*e82f7db8SAndroid Build Coastguard Worker case JDWP_TAG(FLOAT):
438*e82f7db8SAndroid Build Coastguard Worker value.f = inStream_readFloat(stream);
439*e82f7db8SAndroid Build Coastguard Worker break;
440*e82f7db8SAndroid Build Coastguard Worker
441*e82f7db8SAndroid Build Coastguard Worker case JDWP_TAG(DOUBLE):
442*e82f7db8SAndroid Build Coastguard Worker value.d = inStream_readDouble(stream);
443*e82f7db8SAndroid Build Coastguard Worker break;
444*e82f7db8SAndroid Build Coastguard Worker
445*e82f7db8SAndroid Build Coastguard Worker case JDWP_TAG(INT):
446*e82f7db8SAndroid Build Coastguard Worker value.i = inStream_readInt(stream);
447*e82f7db8SAndroid Build Coastguard Worker break;
448*e82f7db8SAndroid Build Coastguard Worker
449*e82f7db8SAndroid Build Coastguard Worker case JDWP_TAG(LONG):
450*e82f7db8SAndroid Build Coastguard Worker value.j = inStream_readLong(stream);
451*e82f7db8SAndroid Build Coastguard Worker break;
452*e82f7db8SAndroid Build Coastguard Worker
453*e82f7db8SAndroid Build Coastguard Worker case JDWP_TAG(SHORT):
454*e82f7db8SAndroid Build Coastguard Worker value.s = inStream_readShort(stream);
455*e82f7db8SAndroid Build Coastguard Worker break;
456*e82f7db8SAndroid Build Coastguard Worker
457*e82f7db8SAndroid Build Coastguard Worker case JDWP_TAG(BOOLEAN):
458*e82f7db8SAndroid Build Coastguard Worker value.z = inStream_readBoolean(stream);
459*e82f7db8SAndroid Build Coastguard Worker break;
460*e82f7db8SAndroid Build Coastguard Worker default:
461*e82f7db8SAndroid Build Coastguard Worker stream->error = JDWP_ERROR(INVALID_TAG);
462*e82f7db8SAndroid Build Coastguard Worker break;
463*e82f7db8SAndroid Build Coastguard Worker }
464*e82f7db8SAndroid Build Coastguard Worker }
465*e82f7db8SAndroid Build Coastguard Worker if (typeKeyPtr) {
466*e82f7db8SAndroid Build Coastguard Worker *typeKeyPtr = typeKey;
467*e82f7db8SAndroid Build Coastguard Worker }
468*e82f7db8SAndroid Build Coastguard Worker return value;
469*e82f7db8SAndroid Build Coastguard Worker }
470*e82f7db8SAndroid Build Coastguard Worker
471*e82f7db8SAndroid Build Coastguard Worker static jboolean
deleteRef(void * elementPtr,void * arg)472*e82f7db8SAndroid Build Coastguard Worker deleteRef(void *elementPtr, void *arg)
473*e82f7db8SAndroid Build Coastguard Worker {
474*e82f7db8SAndroid Build Coastguard Worker JNIEnv *env = arg;
475*e82f7db8SAndroid Build Coastguard Worker jobject *refPtr = elementPtr;
476*e82f7db8SAndroid Build Coastguard Worker commonRef_idToRef_delete(env, *refPtr);
477*e82f7db8SAndroid Build Coastguard Worker return JNI_TRUE;
478*e82f7db8SAndroid Build Coastguard Worker }
479*e82f7db8SAndroid Build Coastguard Worker
480*e82f7db8SAndroid Build Coastguard Worker void
inStream_destroy(PacketInputStream * stream)481*e82f7db8SAndroid Build Coastguard Worker inStream_destroy(PacketInputStream *stream)
482*e82f7db8SAndroid Build Coastguard Worker {
483*e82f7db8SAndroid Build Coastguard Worker if (stream->packet.type.cmd.data != NULL) {
484*e82f7db8SAndroid Build Coastguard Worker jvmtiDeallocate(stream->packet.type.cmd.data);
485*e82f7db8SAndroid Build Coastguard Worker }
486*e82f7db8SAndroid Build Coastguard Worker
487*e82f7db8SAndroid Build Coastguard Worker (void)bagEnumerateOver(stream->refs, deleteRef, (void *)getEnv());
488*e82f7db8SAndroid Build Coastguard Worker bagDestroyBag(stream->refs);
489*e82f7db8SAndroid Build Coastguard Worker }
490