Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

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 }