Source code: org/metacosm/bin2xml/Bin2XML.java
1 /*
2 bin2xml, a serialized to XML translator
3 Copyright (C) 2000-2001 Metacosm Development Team
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 package org.metacosm.bin2xml;
21
22 import java.io.ObjectStreamConstants;
23 import java.io.ObjectInputStream.GetField;
24 import java.io.DataInputStream;
25 import java.io.FileInputStream;
26 import java.io.FileOutputStream;
27 import java.io.PrintStream;
28 import java.io.IOException;
29 import java.util.HashMap;
30 import java.util.ArrayList;
31
32 /**
33 * Converts a binary serialized file into XML.<br>
34 * There is no support for Block Data mode of serialization.
35 * There is no exhaustive tests on binary format: it is supposed to be correct.
36 * No support for JDK 1.3 modifications
37 */
38 public class Bin2XML implements ObjectStreamConstants {
39
40 /**
41 * Does the translation from binary to XML.<br>
42 * Takes from one to three arguments:<br>
43 * <ul><li>First argument = binary filename</li>
44 * <li>Optional second argument = DTD output filename</li>
45 * <li>Optional third argument = XML output filename</li></ul>
46 * Default output filenames are input_filename.dtd and input_filename.xml.
47 * Exits in case of to few or to many arguments, or if problems with outputs.
48 */
49 static public final void main(String[] argv) {
50 PrintStream DTD_output = System.out;
51 PrintStream XML_output = System.out;
52 if (argv.length != 1) {
53 usage();
54 System.exit(1);
55 }
56 try {
57 XML_output = new PrintStream( new FileOutputStream( argv[0] + XML_EXTENSION));
58 DTD_output = new PrintStream( new FileOutputStream( argv[0] + DTD_EXTENSION));
59 } catch ( java.io.FileNotFoundException e) {
60 System.err.println(e.getMessage());
61 System.exit(1);
62 }
63
64 new Bin2XML(argv[0], DTD_output, XML_output).run();
65 }
66
67 /**
68 * Prints a usage message.
69 */
70 static public final void usage() {
71 System.out.println("Usage: java Bin2XML binary_file [DTD_output] [XML_output]");
72 }
73
74 /**
75 * Exits in file not found.
76 * @param fileName input binary filename
77 * @param ps_dtd java.io.PrintStream used for DTD
78 * @param ps_xml java.io.PrintStream used for XML
79 */
80 public Bin2XML( String fileName, PrintStream ps_dtd, PrintStream ps_xml) {
81 try {
82 m_dis = new DataInputStream( new FileInputStream( fileName));
83 } catch ( java.io.FileNotFoundException e) {
84 System.err.println(e.getMessage());
85 System.exit(1);
86 }
87 m_dtd = ps_dtd;
88 m_xml = ps_xml;
89 ref = new ArrayList();
90 hash = new HashMap();
91 hash.put("Z", ClassDescription.BOOLEAN);
92 hash.put("B", ClassDescription.BYTE);
93 hash.put("C", ClassDescription.CHAR);
94 hash.put("D", ClassDescription.DOUBLE);
95 hash.put("F", ClassDescription.FLOAT);
96 hash.put("I", ClassDescription.INT);
97 hash.put("J", ClassDescription.LONG);
98 hash.put("S", ClassDescription.SHORT);
99 }
100
101 /**
102 * Debug method which prints references list
103 */
104 void debug() {
105 // print ref
106 System.out.println("*** DEBUG REF ***");
107 for (int i=0; i < ref.size(); ++i) {
108 System.out.println("ref " + i + ": " + ref.get(i).toString());
109 }
110 System.out.println("*****************");
111 }
112
113 /**
114 * Does the translation.
115 * Exits in case of IOException or in invalid (or unsupported) format.
116 * @see InvalidBinaryFormatException
117 */
118 public void run() {
119 try {
120 readHeader();
121 readSomething( false);
122 m_dtd.println( ctag( TOP_TAG));
123 }
124 catch( IOException ioe) {
125 System.err.println("IO Exception");
126 debug();
127 ioe.printStackTrace();
128 System.exit(1);
129 }
130 catch( InvalidBinaryFormatException ibfe) {
131 System.err.println(ibfe.getMessage());
132 debug();
133 System.exit(1);
134 }
135 /* only to debug
136 finally {
137 debug();
138 }
139 */
140 }
141
142 /**
143 * Reads the header of serialization format.
144 */
145 void readHeader() throws IOException, InvalidBinaryFormatException {
146 short sm = m_dis.readShort();
147 short sv = m_dis.readShort();
148 if ( sm != STREAM_MAGIC || sv != STREAM_VERSION) {
149 throw new InvalidBinaryFormatException("header");
150 } else {
151 m_xml.println( encoding());
152 m_dtd.println( otag( TOP_TAG));
153 m_dtd.println( tag( MAGIC_TAG, Integer.toHexString(sm & 0x0000ffff)));
154 m_dtd.println( tag( VERSION_TAG, Short.toString(sv)));
155 }
156 }
157
158 /**
159 * Reads something (object, array, string, null or reference).
160 */
161 // methods calling readSomething should not encountered some TC_ types, if binary is correct
162 // a method expect 'one of (TC_OBJECT, TC_ARRAY, TC_STRING)' OR TC_NULL OR TC_REFERENCE
163 void readSomething( boolean emptyObject) throws IOException, InvalidBinaryFormatException {
164 switch( m_dis.readByte()) {
165 case TC_OBJECT:
166 m_xml.println( otag(OBJECT_TAG));
167 if (!emptyObject) {
168 readObject();
169 }
170 m_xml.println( ctag(OBJECT_TAG));
171 break;
172 case TC_ARRAY:
173 m_xml.println( otag(ARRAY_TAG));
174 readArray();
175 m_xml.println( ctag(ARRAY_TAG));
176 break;
177 case TC_STRING:
178 m_xml.println( tag(STRING_TAG, readString()));
179 break;
180 case TC_NULL:
181 m_xml.println( optag(NULL_OPTAG));
182 break;
183 case TC_REFERENCE: // should not be the first item
184 m_xml.println( optag(OBJECT_TAG, REF_PARAM, Integer.toString(m_dis.readInt() - baseWireHandle)));
185 break;
186 default:
187 throw new InvalidBinaryFormatException("data type determination");
188 }
189 }
190
191 /*
192 **
193 * Reads an object reference or an empty object.
194 *
195 void readObjectReferenceOrEmptyObject() throws IOException, InvalidBinaryFormatException {
196 switch( m_dis.readByte()) {
197 case TC_OBJECT:
198 m_xml.println( optag(OBJECT_TAG));
199 break;
200 case TC_REFERENCE:
201 m_xml.println( optag(OBJECT_TAG, REF_PARAM, Integer.toString(m_dis.readInt() - baseWireHandle)));
202 break;
203 case TC_NULL: m_xml.println( optag(NULL_OPTAG));
204 break;
205 default:
206 throw new InvalidBinaryFormatException("data type determination");
207 }
208 }
209 */
210
211 /**
212 * Reads an object. Called after a TC_OBJECT is found.<br>
213 * Reads first a class description or a reference to a class description,
214 * then data.
215 * @see TC_OBJECT
216 * @see readClassDescription
217 * @see readClassReference
218 */
219 void readObject() throws IOException, InvalidBinaryFormatException {
220 byte whatsNext = m_dis.readByte();
221 ReturnedClassDescription returnedClassDesc;
222 boolean emptyObject = false;
223 ClassDescription classDesc;
224 if (whatsNext == TC_CLASSDESC) {
225 returnedClassDesc = readClassDescription( false);
226 classDesc = returnedClassDesc.classDescription;
227 emptyObject = returnedClassDesc.emptyObject;
228 } else { // ref
229 classDesc = readClassReference( whatsNext);
230 emptyObject = classDesc.emptyObject();
231 }
232
233 //DEBUG
234 if (emptyObject) {
235 m_xml.println("##REF " + ref.size() + " ## Object empty");
236 } else {
237 m_xml.println("##REF " + ref.size() + " ## Object");
238 }
239 ref.add( ClassInstance.INSTANCE);
240
241 // read data
242 if (!emptyObject) {
243 classDesc.readData(this);
244 }
245 }
246
247 /**
248 * Reads an array. Called after a TC_ARRAY is found.<br>
249 * Reads first a class description or a reference to a class description,
250 * then data.
251 * @see TC_ARRAY
252 * @see readClassDescription
253 * @see readClassReference
254 */
255 void readArray() throws IOException, InvalidBinaryFormatException {
256 byte whatsNext = m_dis.readByte();
257 boolean emptyObject = false;
258 ClassDescriptionArray classDesc;
259 if (whatsNext == TC_CLASSDESC) {
260 ReturnedClassDescription returnedClassDesc = readClassDescription(true);
261 classDesc = (ClassDescriptionArray)returnedClassDesc.classDescription;
262 emptyObject = returnedClassDesc.emptyObject;
263 } else {
264 classDesc = (ClassDescriptionArray)readClassReference(whatsNext);
265 emptyObject = classDesc.emptyObject();
266 }
267 int nb = m_dis.readInt();
268 // read nb data
269 ClassDescription itemsClass = classDesc.getItemsClass();
270 if (itemsClass == null) { // itemType was undefined at array declaration
271 itemsClass = (ClassDescription)hash.get(classDesc.getClassName().substring(1));
272 }
273
274 //DEBUG
275 if (emptyObject) {
276 m_xml.println("##REF " + ref.size() + " ## Array of empty objects");
277 } else {
278 m_xml.println("##REF " + ref.size() + " ## Array");
279 }
280 ref.add( ClassInstance.INSTANCE);
281
282 // read data
283 // DEBUG if (!emptyObject) {
284 for (int i = 0; i < nb; ++i) {
285 itemsClass.readData(this);
286 }
287 // }
288 }
289
290 class ReturnedClassDescription {
291 ClassDescription classDescription;
292 boolean emptyObject;
293 }
294
295 /**
296 * Reads a class description.
297 * @param isArray <i>true</i> if class is an array, else <i>false</i>
298 */
299 ReturnedClassDescription readClassDescription( boolean isArray) throws IOException, InvalidBinaryFormatException {
300 m_dtd.println( otag(CLASSDESC_TAG));
301 short lg = m_dis.readShort();
302 byte[] tab_name = new byte[lg];
303 m_dis.readFully( tab_name);
304 String name = new String( tab_name);
305 if (name.charAt(0) != '[') {
306 name = "L" + name + ";";
307 }
308 m_dtd.println( tag(NAME_TAG, name));
309 long sha = m_dis.readLong();
310 m_dtd.println( tag(SIG_TAG, Long.toHexString(sha)));
311 byte sc = m_dis.readByte();
312 m_dtd.println( tag(SC_TAG, Integer.toString(sc))); // TODO explanations
313 short nbFields = m_dis.readShort();
314 ClassDescription classDesc;
315 if (!isArray) {
316 classDesc = new ClassDescription( name, null, nbFields);
317 } else {
318 String arrayClassName = name.substring(1);
319 ClassDescription arrayClass = (ClassDescription)hash.get( arrayClassName);
320 classDesc = new ClassDescriptionArray( name, arrayClass);
321 }
322 hash.put(name, classDesc);
323 //DEBUG
324 if (!isArray) {
325 m_xml.println("##REF " + ref.size()+ " ## ClassDesc (" + nbFields + " fields)");
326 } else {
327 m_xml.println("##REF " + ref.size()+ " ## ClassDescArray");
328 }
329 ref.add(classDesc);
330 for (int i = 0; i < nbFields; i++) {
331 readFieldDescription( classDesc);
332 }
333 if (m_dis.readByte() != TC_ENDBLOCKDATA) {
334 throw new InvalidBinaryFormatException("end data block");
335 }
336 ClassDescription motherClassDesc;
337 byte whatsNext = m_dis.readByte();
338 if (whatsNext == TC_CLASSDESC) {
339 ReturnedClassDescription returnedClassDesc = readClassDescription(false);
340 motherClassDesc = returnedClassDesc.classDescription;
341 } else {
342 motherClassDesc = readClassReference( whatsNext);
343 }
344 classDesc.setMotherClass( motherClassDesc);
345 m_dtd.println( ctag(CLASSDESC_TAG));
346
347 ReturnedClassDescription resul = new ReturnedClassDescription();
348 resul.classDescription = classDesc;
349 resul.emptyObject = (nbFields == 0);
350 return resul;
351 }
352
353 /**
354 * Reads a field description.
355 */
356 void readFieldDescription( ClassDescription classDesc) throws IOException, InvalidBinaryFormatException {
357 byte type = m_dis.readByte();
358 short lg = m_dis.readShort();
359 byte[] tab_name = new byte[lg];
360 m_dis.readFully( tab_name);
361 String name = new String( tab_name);
362 byte whatsNext = 0;
363 if (type == 'L' || type == '[') { // read a reference or a string
364 whatsNext = m_dis.readByte();
365 }
366 switch( (char)type) {
367 case 'B':
368 m_dtd.println( optag(BYTE_TAG, NAME_PARAM, name));
369 classDesc.addByteField();
370 break;
371 case 'C':
372 m_dtd.println( optag(CHAR_TAG, NAME_PARAM, name));
373 classDesc.addCharField();
374 break;
375 case 'D':
376 m_dtd.println( optag(DOUBLE_TAG, NAME_PARAM, name));
377 classDesc.addDoubleField();
378 break;
379 case 'F':
380 m_dtd.println( optag(FLOAT_TAG, NAME_PARAM, name));
381 classDesc.addFloatField();
382 break;
383 case 'I':
384 m_dtd.println( optag(INT_TAG, NAME_PARAM, name));
385 classDesc.addIntField();
386 break;
387 case 'J':
388 m_dtd.println( optag(LONG_TAG, NAME_PARAM, name));
389 classDesc.addLongField();
390 break;
391 case 'L':
392 String className;
393 String buffer = OBJECT_TAG;
394 ClassDescription fieldClass;
395 String params = "";
396 if (whatsNext == TC_STRING) {
397 className = readString();
398 if (className.equals("java/lang/String;")) {
399 //DEBUG
400 m_xml.println("*Meep* String detected");
401 fieldClass = new ClassDescriptionString();
402 } else {
403 fieldClass = (ClassDescription)hash.get( className);
404 }
405 buffer += param(CLASS_PARAM, className);
406 } else {
407 Pair pair = readObjectReference( whatsNext);
408 fieldClass = pair.ref;
409 buffer += pair.param;
410 className = fieldClass.getClassName();
411 }
412 if (fieldClass == null) { // class not yet encountered
413 fieldClass = new ClassDescription( className, name);
414 hash.put( name, fieldClass);
415 //DEBUG
416 m_xml.println("##REF " + ref.size() + " ## object field");
417 ref.add( fieldClass);
418 }
419 buffer += param( NAME_PARAM,name);
420 m_dtd.println( optag( buffer));
421 classDesc.addField( fieldClass);
422 break;
423 case 'S':
424 m_dtd.println( optag(SHORT_TAG, NAME_PARAM, name));
425 classDesc.addShortField();
426 break;
427 case 'Z':
428 m_dtd.println( optag(BOOLEAN_TAG, NAME_PARAM, name));
429 classDesc.addBooleanField();
430 break;
431 case '[':
432 String theBuffer = ARRAY_TAG;
433 String theClassName;
434 ClassDescription theFieldClass;
435 if (whatsNext == TC_STRING) {
436 theClassName = readString();
437 theFieldClass = (ClassDescription)hash.get( theClassName);
438 theBuffer += param(CLASS_PARAM, theClassName);
439
440 if (theFieldClass == null) {
441 String arrayClassName = theClassName.substring(1);
442 ClassDescription arrayClass = (ClassDescription)hash.get( arrayClassName);
443 // arrayClass can be null
444 theFieldClass = new ClassDescriptionArray( theClassName, arrayClass);
445 hash.put( theClassName, theFieldClass);
446 //DEBUG
447 m_xml.println("##REF " + ref.size() + " ## array field");
448 ref.add( theFieldClass);
449 }
450 } else {
451 Pair thePair = readObjectReference( whatsNext);
452 theFieldClass = thePair.ref;
453 theBuffer += thePair.param;
454 theClassName = theFieldClass.getClassName();
455 }
456 theBuffer += param( NAME_PARAM, name);
457 m_dtd.println( optag( theBuffer));
458 classDesc.addField( theFieldClass);
459 break;
460 default:
461 throw new InvalidBinaryFormatException("field type");
462 }
463 }
464
465 /**
466 * @return the read String
467 */
468 String readString() throws IOException {
469 short lg = m_dis.readShort();
470 byte[] name = new byte[lg];
471 m_dis.readFully( name);
472 return new String(name);
473 }
474
475 /**
476 * @return the read reference to a class description
477 */
478 ClassDescription readClassReference(byte refType) throws IOException, InvalidBinaryFormatException {
479 ClassDescription classDesc = null;
480 switch(refType) {
481 case TC_BASE:
482 break;
483 case TC_REFERENCE:
484 int reference = m_dis.readInt() - baseWireHandle;
485 m_dtd.println( optag(CLASSDESC_TAG, REF_PARAM, Integer.toString(reference)));
486 classDesc = (ClassDescription)ref.get(reference);
487 break;
488 default:
489 throw new InvalidBinaryFormatException("reference");
490 }
491 return classDesc;
492 }
493
494 class Pair {
495 public ClassDescription ref;
496 public String param;
497 }
498
499 /**
500 * @return a couple 'the read reference to an object','parameter string'
501 */
502 Pair readObjectReference(byte refType) throws IOException, InvalidBinaryFormatException {
503 Pair pair = new Pair();
504 pair.ref = null;
505 pair.param = "";
506 switch(refType) {
507 case TC_BASE:
508 break;
509 case TC_REFERENCE:
510 int reference = m_dis.readInt() - baseWireHandle;
511 pair.param = param(REF_PARAM, Integer.toString(reference));
512 //DEBUG
513 try {
514 pair.ref = (ClassDescription)ref.get(reference);
515 } catch( java.lang.Exception e) {
516 debug();
517 }
518 break;
519 default:
520 throw new InvalidBinaryFormatException("reference");
521 }
522 return pair;
523 }
524
525 /**
526 * Reads and outputs a boolean.
527 */
528 void readBoolean() throws IOException {
529 m_xml.println( tag( BOOLEAN_TAG, new Boolean(m_dis.readBoolean()).toString()));
530 }
531
532 /**
533 * Reads and outputs a byte.
534 */
535 void readByte() throws IOException {
536 m_xml.println( tag( BYTE_TAG, Byte.toString(m_dis.readByte())));
537 }
538
539 /**
540 * Reads and outputs a char.
541 */
542 void readChar() throws IOException {
543 m_xml.println( tag( CHAR_TAG, new Character(m_dis.readChar()).toString()));
544 }
545
546 /**
547 * Reads and outputs a double.
548 */
549 void readDouble() throws IOException {
550 m_xml.println( tag( DOUBLE_TAG, Double.toString(m_dis.readDouble())));
551 }
552
553 /**
554 * Reads and outputs a float.
555 */
556 void readFloat() throws IOException {
557 m_xml.println( tag( FLOAT_TAG, Float.toString(m_dis.readFloat())));
558 }
559
560 /**
561 * Reads and outputs an int.
562 */
563 void readInt() throws IOException {
564 m_xml.println( tag( INT_TAG, Integer.toString(m_dis.readInt())));
565 }
566
567 /**
568 * Reads and outputs a long.
569 */
570 void readLong() throws IOException {
571 m_xml.println( tag( LONG_TAG, Long.toString(m_dis.readLong())));
572 }
573
574 /**
575 * Reads and outputs a short.
576 */
577 void readShort() throws IOException {
578 m_xml.println( tag( SHORT_TAG, Short.toString(m_dis.readShort())));
579 }
580
581 /**
582 * Reads and outputs a String.
583 */
584 void readStringData() throws IOException {
585 byte whatsNext = m_dis.readByte();
586 String str;
587 if (whatsNext == TC_STRING) {
588 str = readString();
589 m_xml.println( tag( STRING_TAG, str));
590 ref.add( str);
591 } else {
592 Integer index = new Integer(m_dis.readInt() - baseWireHandle);
593 m_xml.println( optag( STRING_TAG, REF_PARAM, index.toString()));
594 }
595 }
596
597 /**
598 * @return an opening <i>tagname</i> tag
599 */
600 private final static String otag( String tagname) {
601 return "<" + tagname + ">";
602 }
603
604 /**
605 * @return an closing <i>tagname</i> tag
606 */
607 private final static String ctag( String tagname) {
608 return "</" + tagname + ">";
609 }
610
611 /**
612 * @return a param and its value
613 */
614 private final static String param( String name, String value) {
615 return " " + name+ "=\"" + value + "\"";
616 }
617
618 /**
619 * @return <i>tagcontent</i> contains between <i>tagname</i> tags
620 */
621 private final static String tag( String tagname, String tagcontent) {
622 return otag(tagname) + tagcontent + ctag(tagname);
623 }
624
625 /**
626 * @return a one part <i>tagname</i> tag with parameter
627 */
628 private final static String optag( String tagname, String parName,
629 String parValue) {
630 return "<" + tagname + param(parName, parValue) + "/>";
631 }
632
633 /**
634 * @return a one part <i>tagname</i> tag with parameters
635 */
636 private final static String optag( String tagname, String parName1,
637 String parValue1, String parName2,
638 String parValue2) {
639 return "<" + tagname + param(parName1, parValue1)
640 + param(parName2, parValue2) + "/>";
641 }
642
643 /**
644 * @return a one part <i>tagname</i> tag
645 */
646 private final static String optag( String tagname) {
647 return "<" + tagname + "/>";
648 }
649
650 /**
651 * FIXME
652 */
653 private final static String encoding() {
654 return "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"; //FIXME
655 }
656
657 /**
658 * Identifier for serialized binary (defined by Sun)
659 */
660 private final static short STREAM_MAGIC = (short)0xaced;
661 /**
662 * Stream version (defined by Sun)
663 */
664 private final static short STREAM_VERSION = 5;
665
666 /**
667 * First tag value (defined by Sun)
668 */
669 private final static byte TC_BASE = 0x70;
670
671 /**
672 * Code for null (defined by Sun)
673 */
674 private final static byte TC_NULL = 0x70;
675
676 /**
677 * Code for reference (defined by Sun)
678 */
679 private final static byte TC_REFERENCE = 0x71;
680
681 /**
682 * Code for new class description (defined by Sun)
683 */
684 private final static byte TC_CLASSDESC = 0x72;
685
686 /**
687 * Code for new object (defined by Sun)
688 */
689 private final static byte TC_OBJECT = 0x73;
690
691 /**
692 * Code for new String (defined by Sun)
693 */
694 private final static byte TC_STRING = 0x74;
695
696 /**
697 * Code for new array (defined by Sun)
698 */
699 private final static byte TC_ARRAY = 0x75;
700
701 /**
702 * Code for class (defined by Sun)<br>
703 * <b>UNUSED BY Bin2XML</b>
704 */
705 private final static byte TC_CLASS = 0x76;
706
707 /**
708 * Code for block data (defined by Sun)
709 * <b>UNUSED BY Bin2XML</b>
710 */
711 private final static byte TC_BLOCKDATA = 0x77;
712
713 /**
714 * Code for end of block (defined by Sun)
715 */
716 private final static byte TC_ENDBLOCKDATA = 0x78;
717
718 /**
719 * Code for reset stream context (defined by Sun)
720 * <b>UNUSED BY Bin2XML</b>
721 */
722 private final static byte TC_RESET = 0x79;
723
724 /**
725 * Code for block data long mode (defined by Sun)
726 * <b>UNUSED BY Bin2XML</b>
727 */
728 private final static byte TC_BLOCKDATALONG = 0x7A;
729
730 /**
731 * Code for exception (defined by Sun)
732 * <b>UNUSED BY Bin2XML</b>
733 */
734 private final static byte TC_EXCEPTION = 0x7B;
735
736 /**
737 * Last tag value (defined by Sun)
738 * <b>UNUSED BY Bin2XML</b>
739 */
740 private final static byte TC_MAX = 0x7B;
741
742
743 /**
744 * Bit mask for classes implementing writeObject() serialization (defined by Sun)
745 */
746 private final static byte SC_WRITE_METHOD = 0x01;
747
748 /**
749 * Bit mask for classes implementing block data mode serialization (defined by Sun)
750 */
751 private final static byte SC_BLOCK_DATA = 0x08;
752
753 /**
754 * Bit mask for classes serializable (defined by Sun)
755 */
756 private final static byte SC_SERIALIZABLE = 0x02;
757
758 /**
759 * Bit mask for classes externalizable (defined by Sun)
760 */
761 private final static byte SC_EXTERNALIZABLE = 0x04;
762
763
764 /**
765 * Value for base reference (= reference 0) (defined by Sun)
766 */
767 private final static int baseWireHandle = 0x7e0000; // ref 0
768
769
770 /**
771 * DTD extension
772 */
773 private final static String DTD_EXTENSION = ".dtd";
774
775 /**
776 * XML extension
777 */
778 private final static String XML_EXTENSION = ".xml";
779
780 /**
781 * Default outputs for DTD and XML streams
782 */
783 private final static String DEFAULT_OUTPUTS = "System.out";
784
785
786 /**
787 * Tag for arrays
788 */
789 private final static String ARRAY_TAG = "array";
790
791 /**
792 * Tag for booleans
793 */
794 private final static String BOOLEAN_TAG = "boolean";
795
796 /**
797 * Tag for bytes
798 */
799 private final static String BYTE_TAG = "byte";
800
801 /**
802 * Tag for chars
803 */
804 private final static String CHAR_TAG = "char";
805
806 /**
807 * Tag for class descriptions
808 */
809 private final static String CLASSDESC_TAG = "classdesc";
810
811 /**
812 * Tag for doubles
813 */
814 private final static String DOUBLE_TAG = "double";
815
816 /**
817 * Tag for floats
818 */
819 private final static String FLOAT_TAG = "float";
820
821 /**
822 * Tag for ints
823 */
824 private final static String INT_TAG = "int";
825
826 /**
827 * Tag for longs
828 */
829 private final static String LONG_TAG = "long";
830
831 /**
832 * Tag for magic number
833 */
834 private final static String MAGIC_TAG = "magic";
835
836 /**
837 * Tag for name
838 */
839 private final static String NAME_TAG = "name";
840
841 /**
842 * Tag for objects
843 */
844 private final static String OBJECT_TAG = "object";
845
846 /**
847 * Tag for Stream Class bit flags
848 */
849 private final static String SC_TAG = "sc";
850
851 /**
852 * Tag for shorts
853 */
854 private final static String SHORT_TAG = "short";
855
856 /**
857 * Tag for class SHA signature
858 */
859 private final static String SIG_TAG = "sig";
860
861 /**
862 * Tag for Strings
863 */
864 private final static String STRING_TAG = "string";
865
866 /**
867 * Top level tag
868 */
869 private final static String TOP_TAG = "top";
870
871 /**
872 * Tag for serialization version number
873 */
874 private final static String VERSION_TAG = "version";
875
876 /**
877 * One part tag for null
878 */
879 private final static String NULL_OPTAG = "null";
880
881 /**
882 * Parameter name for items class name for an array
883 */
884 private final static String CLASS_PARAM = "class";
885
886 /**
887 * Parameter name for class name
888 */
889 private final static String NAME_PARAM = "name";
890
891 /**
892 * Parameter name for references
893 */
894 private final static String REF_PARAM = "ref";
895
896 /**
897 * Input stream for serialized binary
898 */
899 private DataInputStream m_dis;
900
901 /**
902 * Output stream for DTD
903 */
904 private PrintStream m_dtd;
905
906 /**
907 * Output stream for XML
908 */
909 private PrintStream m_xml;
910
911 /**
912 * ArrayList containing references on objects and class descriptions
913 */
914 private ArrayList ref;
915
916 /**
917 * Link class names and references
918 */
919 private HashMap hash;
920 }