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: import ;
52:
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60:
61:
66: public class MessageHeader
67: implements IDLEntity
68: {
69:
72: private static final long serialVersionUID = 1;
73:
74:
77: public static final byte REQUEST = 0;
78:
79:
82: public static final byte REPLY = 1;
83:
84:
87: public static final byte CANCEL_REQUEST = 2;
88:
89:
94: public static final byte LOCATE_REQUEST = 3;
95:
96:
100: public static final byte LOCATE_REPLY = 4;
101:
102:
105: public static final byte CLOSE_CONNECTION = 5;
106:
107:
110: public static final byte MESSAGE_ERROR = 6;
111:
112:
116: public static final byte FRAGMENT = 7;
117:
118:
121: public static final byte[] MAGIC = new byte[] { 'G', 'I', 'O', 'P' };
122:
123:
126: protected static String[] types = new String[] { "Request", "Reply",
127: "Cancel", "Locate request", "Locate reply", "Close connection", "Error",
128: "Fragment" };
129:
130:
133: public Version version;
134:
135:
138: public byte flags = 0;
139:
140:
143: public byte message_type = REQUEST;
144:
145:
148: public int message_size = 0;
149:
150:
153: public MessageHeader()
154: {
155: version = new Version(1, 0);
156: }
157:
158:
164: public MessageHeader(int major, int minor)
165: {
166: version = new Version(major, minor);
167: }
168:
169:
173: public boolean isBigEndian()
174: {
175: return (flags & 0x1) == 0;
176: }
177:
178:
181: public boolean moreFragmentsFollow()
182: {
183: return (flags & 0x2) != 0;
184: }
185:
186:
192: public void setBigEndian(boolean use_big_endian)
193: {
194: if (use_big_endian)
195: flags = (byte) (flags & ~1);
196: else
197: flags = (byte) (flags | 1);
198: }
199:
200:
203: public int getHeaderSize()
204: {
205: return 12;
206: }
207:
208:
215: public String getTypeString(int type)
216: {
217: try
218: {
219: return types[type];
220: }
221: catch (ArrayIndexOutOfBoundsException ex)
222: {
223: return "unknown type (" + type + ")";
224: }
225: }
226:
227:
234: public ReplyHeader create_reply_header()
235: {
236: if (version.since_inclusive(1, 2))
237: return new gnu.CORBA.GIOP.v1_2.ReplyHeader();
238: else
239: return new gnu.CORBA.GIOP.v1_0.ReplyHeader();
240: }
241:
242:
249: public RequestHeader create_request_header()
250: {
251: if (version.since_inclusive(1, 2))
252: return new gnu.CORBA.GIOP.v1_2.RequestHeader();
253: else
254: return new gnu.CORBA.GIOP.v1_0.RequestHeader();
255: }
256:
257:
260: public CancelHeader create_cancel_header()
261: {
262: return new gnu.CORBA.GIOP.v1_0.CancelHeader();
263: }
264:
265:
268: public ErrorMessage create_error_message()
269: {
270: return new ErrorMessage(version);
271: }
272:
273:
279: public void read(java.io.InputStream istream)
280: throws MARSHAL, EOFException
281: {
282: try
283: {
284: byte[] xMagic = new byte[MAGIC.length];
285: int r = istream.read(xMagic);
286: int minor;
287: if (! Arrays.equals(xMagic, MAGIC))
288: {
289: StringBuffer b = new StringBuffer();
290: if (r == - 1)
291: {
292: b.append("Immediate EOF");
293: minor = Minor.EOF;
294: }
295: else
296: {
297: minor = Minor.Giop;
298: b.append(r + " bytes: ");
299: for (int i = 0; i < xMagic.length; i++)
300: {
301: b.append(Integer.toHexString(xMagic[i] & 0xFF));
302: b.append(' ');
303: }
304: }
305: MARSHAL m = new MARSHAL("Not a GIOP message: " + b);
306: m.minor = minor;
307: throw m;
308: }
309:
310: version = Version.read_version(istream);
311:
312: AbstractDataInput din;
313:
314: flags = (byte) istream.read();
315:
316:
317: if (isBigEndian())
318: din = new BigEndianInputStream(istream);
319: else
320: din = new LittleEndianInputStream(istream);
321:
322: message_type = (byte) din.read();
323:
324: message_size = din.readInt();
325: }
326: catch (IOException ex)
327: {
328: MARSHAL t = new MARSHAL();
329: t.minor = Minor.Header;
330: t.initCause(ex);
331: throw t;
332: }
333: }
334:
335:
340: public String toString()
341: {
342: return "GIOP " + version + ", " + (isBigEndian() ? "Big" : "Little")
343: + " endian, " + getTypeString(message_type) + ", " + message_size
344: + " bytes. ";
345: }
346:
347:
352: public void write(java.io.OutputStream out)
353: {
354: try
355: {
356: AbstractDataOutput dout;
357:
358: if (isBigEndian())
359: dout = new BigEndianOutputStream(out);
360: else
361: dout = new LittleEndianOutputStream(out);
362:
363:
364: dout.write(MAGIC);
365:
366:
367: version.write((OutputStream) dout);
368: dout.write(flags);
369: dout.write(message_type);
370: dout.writeInt(message_size);
371: }
372: catch (IOException ex)
373: {
374: MARSHAL t = new MARSHAL(ex.getMessage());
375: t.minor = Minor.Header;
376: t.initCause(ex);
377: throw t;
378: }
379: }
380:
381:
390: public byte[] readMessage(InputStream source, Socket service, int to_read,
391: int to_pause)
392: {
393: try
394: {
395: byte[] r = new byte[message_size];
396:
397: int n = 0;
398: if (service != null)
399: service.setSoTimeout(to_read);
400:
401: reading: while (n < r.length)
402: {
403: n += source.read(r, n, r.length - n);
404: }
405: if (service != null)
406: service.setSoTimeout(to_pause);
407:
408:
409: if (moreFragmentsFollow())
410: {
411: ByteArrayOutputStream buffer = new ByteArrayOutputStream(
412: 2 * r.length);
413: buffer.write(r);
414:
415: if (r.length < 10)
416:
417:
418: r = new byte[1024];
419:
420: MessageHeader h2 = new MessageHeader();
421:
422: do
423: {
424: h2.read(source);
425:
426: int dn;
427:
428: n = 0;
429: reading: while (n < h2.message_size)
430: {
431: dn = source.read(r, 0, h2.message_size - n);
432:
433: if (n == 0 && service != null)
434: service.setSoTimeout(to_read);
435:
436: if (n == 0 && version.since_inclusive(1, 2))
437: {
438:
439: buffer.write(r, 4, dn - 4);
440: }
441: else
442: buffer.write(r, 0, dn);
443: n = +dn;
444: }
445:
446: if (service != null)
447: service.setSoTimeout(to_pause);
448: }
449: while (h2.moreFragmentsFollow());
450: return buffer.toByteArray();
451: }
452: else
453: return r;
454: }
455: catch (IOException ioex)
456: {
457: MARSHAL m = new MARSHAL("Unable to read the message continuation.");
458: m.minor = Minor.Header;
459: m.initCause(ioex);
460: throw m;
461: }
462: }