1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49:
50: import ;
51:
52: import ;
53: import ;
54:
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62:
63:
68: public class MessageHeader
69: implements IDLEntity
70: {
71:
74: private static final long serialVersionUID = 1;
75:
76:
79: public static final byte REQUEST = 0;
80:
81:
84: public static final byte REPLY = 1;
85:
86:
89: public static final byte CANCEL_REQUEST = 2;
90:
91:
96: public static final byte LOCATE_REQUEST = 3;
97:
98:
102: public static final byte LOCATE_REPLY = 4;
103:
104:
107: public static final byte CLOSE_CONNECTION = 5;
108:
109:
112: public static final byte MESSAGE_ERROR = 6;
113:
114:
118: public static final byte FRAGMENT = 7;
119:
120:
123: public static final byte[] MAGIC = new byte[] { 'G', 'I', 'O', 'P' };
124:
125:
128: protected static String[] types = new String[] { "Request", "Reply",
129: "Cancel", "Locate request", "Locate reply", "Close connection", "Error",
130: "Fragment" };
131:
132:
135: public Version version;
136:
137:
140: public byte flags = 0;
141:
142:
145: public byte message_type = REQUEST;
146:
147:
150: public int message_size = 0;
151:
152:
155: public MessageHeader()
156: {
157: version = new Version(1, 0);
158: }
159:
160:
166: public MessageHeader(int major, int minor)
167: {
168: version = new Version(major, minor);
169: }
170:
171:
175: public boolean isBigEndian()
176: {
177: return (flags & 0x1) == 0;
178: }
179:
180:
183: public boolean moreFragmentsFollow()
184: {
185: return (flags & 0x2) != 0;
186: }
187:
188:
194: public void setBigEndian(boolean use_big_endian)
195: {
196: if (use_big_endian)
197: flags = (byte) (flags & ~1);
198: else
199: flags = (byte) (flags | 1);
200: }
201:
202:
205: public int getHeaderSize()
206: {
207: return 12;
208: }
209:
210:
217: public String getTypeString(int type)
218: {
219: try
220: {
221: return types[type];
222: }
223: catch (ArrayIndexOutOfBoundsException ex)
224: {
225: return "unknown type (" + type + ")";
226: }
227: }
228:
229:
236: public ReplyHeader create_reply_header()
237: {
238: if (version.since_inclusive(1, 2))
239: return new gnu.CORBA.GIOP.v1_2.ReplyHeader();
240: else
241: return new gnu.CORBA.GIOP.v1_0.ReplyHeader();
242: }
243:
244:
251: public RequestHeader create_request_header()
252: {
253: if (version.since_inclusive(1, 2))
254: return new gnu.CORBA.GIOP.v1_2.RequestHeader();
255: else
256: return new gnu.CORBA.GIOP.v1_0.RequestHeader();
257: }
258:
259:
262: public CancelHeader create_cancel_header()
263: {
264: return new gnu.CORBA.GIOP.v1_0.CancelHeader();
265: }
266:
267:
270: public ErrorMessage create_error_message()
271: {
272: return new ErrorMessage(version);
273: }
274:
275:
281: public void read(java.io.InputStream istream)
282: throws MARSHAL, EOFException
283: {
284: try
285: {
286: byte[] xMagic = new byte[MAGIC.length];
287: int r = istream.read(xMagic);
288: int minor;
289: if (! Arrays.equals(xMagic, MAGIC))
290: {
291: CPStringBuilder b = new CPStringBuilder();
292: if (r == - 1)
293: {
294: b.append("Immediate EOF");
295: minor = Minor.EOF;
296: }
297: else
298: {
299: minor = Minor.Giop;
300: b.append(r + " bytes: ");
301: for (int i = 0; i < xMagic.length; i++)
302: {
303: b.append(Integer.toHexString(xMagic[i] & 0xFF));
304: b.append(' ');
305: }
306: }
307: MARSHAL m = new MARSHAL("Not a GIOP message: " + b);
308: m.minor = minor;
309: throw m;
310: }
311:
312: version = Version.read_version(istream);
313:
314: AbstractDataInput din;
315:
316: flags = (byte) istream.read();
317:
318:
319: if (isBigEndian())
320: din = new BigEndianInputStream(istream);
321: else
322: din = new LittleEndianInputStream(istream);
323:
324: message_type = (byte) din.read();
325:
326: message_size = din.readInt();
327: }
328: catch (IOException ex)
329: {
330: MARSHAL t = new MARSHAL();
331: t.minor = Minor.Header;
332: t.initCause(ex);
333: throw t;
334: }
335: }
336:
337:
342: public String toString()
343: {
344: return "GIOP " + version + ", " + (isBigEndian() ? "Big" : "Little")
345: + " endian, " + getTypeString(message_type) + ", " + message_size
346: + " bytes. ";
347: }
348:
349:
354: public void write(java.io.OutputStream out)
355: {
356: try
357: {
358: AbstractDataOutput dout;
359:
360: if (isBigEndian())
361: dout = new BigEndianOutputStream(out);
362: else
363: dout = new LittleEndianOutputStream(out);
364:
365:
366: dout.write(MAGIC);
367:
368:
369: version.write((OutputStream) dout);
370: dout.write(flags);
371: dout.write(message_type);
372: dout.writeInt(message_size);
373: }
374: catch (IOException ex)
375: {
376: MARSHAL t = new MARSHAL(ex.getMessage());
377: t.minor = Minor.Header;
378: t.initCause(ex);
379: throw t;
380: }
381: }
382:
383:
392: public byte[] readMessage(InputStream source, Socket service, int to_read,
393: int to_pause)
394: {
395: try
396: {
397: byte[] r = new byte[message_size];
398:
399: int n = 0;
400: if (service != null)
401: service.setSoTimeout(to_read);
402:
403: while (n < r.length)
404: {
405: n += source.read(r, n, r.length - n);
406: }
407: if (service != null)
408: service.setSoTimeout(to_pause);
409:
410:
411: if (moreFragmentsFollow())
412: {
413: ByteArrayOutputStream buffer = new ByteArrayOutputStream(
414: 2 * r.length);
415: buffer.write(r);
416:
417: if (r.length < 10)
418:
419:
420: r = new byte[1024];
421:
422: MessageHeader h2 = new MessageHeader();
423:
424: do
425: {
426: h2.read(source);
427:
428: int dn;
429:
430: n = 0;
431: while (n < h2.message_size)
432: {
433: dn = source.read(r, 0, h2.message_size - n);
434:
435: if (n == 0 && service != null)
436: service.setSoTimeout(to_read);
437:
438: if (n == 0 && version.since_inclusive(1, 2))
439: {
440:
441: buffer.write(r, 4, dn - 4);
442: }
443: else
444: buffer.write(r, 0, dn);
445: n = +dn;
446: }
447:
448: if (service != null)
449: service.setSoTimeout(to_pause);
450: }
451: while (h2.moreFragmentsFollow());
452: return buffer.toByteArray();
453: }
454: else
455: return r;
456: }
457: catch (IOException ioex)
458: {
459: MARSHAL m = new MARSHAL("Unable to read the message continuation.");
460: m.minor = Minor.Header;
461: m.initCause(ioex);
462: throw m;
463: }
464: }
465: }