11/* 
2-  * Copyright (c) 2009-2021  jMonkeyEngine 
2+  * Copyright (c) 2009-2025  jMonkeyEngine 
33 * All rights reserved. 
44 * 
55 * Redistribution and use in source and binary forms, with or without 
3838import  com .jme3 .export .Savable ;
3939import  com .jme3 .export .SavableClassUtil ;
4040import  com .jme3 .math .FastMath ;
41- import  java .io .*;
41+ 
42+ import  java .io .BufferedOutputStream ;
43+ import  java .io .ByteArrayOutputStream ;
44+ import  java .io .File ;
45+ import  java .io .FileOutputStream ;
46+ import  java .io .IOException ;
47+ import  java .io .OutputStream ;
4248import  java .util .ArrayList ;
4349import  java .util .HashMap ;
4450import  java .util .IdentityHashMap ;
116122 * 
117123 * @author Joshua Slack 
118124 */ 
119- 
120125public  class  BinaryExporter  implements  JmeExporter  {
121-      private   static   final   Logger   logger  =  Logger . getLogger ( BinaryExporter . class 
122-              .getName ());
126+ 
127+     private   static   final   Logger   logger  =  Logger . getLogger ( BinaryExporter . class .getName ());
123128
124129    protected  int  aliasCount  = 1 ;
125130    protected  int  idCount  = 1 ;
126131
127-     private  final  IdentityHashMap <Savable , BinaryIdContentPair > contentTable 
128-              = new  IdentityHashMap <>();
129- 
130-     protected  HashMap <Integer , Integer > locationTable 
131-              = new  HashMap <>();
132+     private  final  IdentityHashMap <Savable , BinaryIdContentPair > contentTable  = new  IdentityHashMap <>();
133+     protected  HashMap <Integer , Integer > locationTable  = new  HashMap <>();
132134
133135    // key - class name, value = bco 
134-     private  final  HashMap <String , BinaryClassObject > classes 
135-              = new  HashMap <>();
136- 
136+     private  final  HashMap <String , BinaryClassObject > classes  = new  HashMap <>();
137137    private  final  ArrayList <Savable > contentKeys  = new  ArrayList <>();
138138
139139    public  static  boolean  debug  = false ;
140140    public  static  boolean  useFastBufs  = true ;
141141
142+     /** 
143+      * Constructs a new {@code BinaryExporter}. 
144+      */ 
142145    public  BinaryExporter () {
143146    }
144147
148+     /** 
149+      * Returns a new instance of {@code BinaryExporter}. 
150+      * 
151+      * @return A new {@code BinaryExporter} instance. 
152+      */ 
145153    public  static  BinaryExporter  getInstance () {
146154        return  new  BinaryExporter ();
147155    }
148156
149157    /** 
150158     * Saves the object into memory then loads it from memory. 
151-      * 
152159     * Used by tests to check if the persistence system is working. 
153160     * 
154161     * @param <T> The type of savable. 
@@ -163,9 +170,11 @@ public static <T extends Savable> T saveAndLoad(AssetManager assetManager, T obj
163170        try  {
164171            BinaryExporter  exporter  = new  BinaryExporter ();
165172            exporter .save (object , baos );
173+ 
166174            BinaryImporter  importer  = new  BinaryImporter ();
167175            importer .setAssetManager (assetManager );
168176            return  (T ) importer .load (baos .toByteArray ());
177+ 
169178        } catch  (IOException  ex ) {
170179            // Should never happen. 
171180            throw  new  AssertionError (ex );
@@ -191,28 +200,25 @@ public void save(Savable object, OutputStream os) throws IOException {
191200        // write out tag table 
192201        int  classTableSize  = 0 ;
193202        int  classNum  = classes .keySet ().size ();
194-         int  aliasSize  = ((int ) FastMath .log (classNum , 256 ) + 1 ); // make all 
195-                                                                   // aliases a 
196-                                                                   // fixed width 
203+         int  aliasSize  = ((int ) FastMath .log (classNum , 256 ) + 1 ); // make all aliases a fixed width 
197204
198205        os .write (ByteUtils .convertToBytes (classNum )); // 3. "number of classes" 
199206        for  (String  key  : classes .keySet ()) {
200207            BinaryClassObject  bco  = classes .get (key );
201208
202209            // write alias 
203-             byte [] aliasBytes  = fixClassAlias (bco .alias ,
204-                     aliasSize );
210+             byte [] aliasBytes  = fixClassAlias (bco .alias , aliasSize );
205211            os .write (aliasBytes );                     // 4. "class alias" 
206212            classTableSize  += aliasSize ;
207213
208214            // jME3 NEW: Write class hierarchy version numbers 
209-             os .write (  bco .classHierarchyVersions .length   );
210-             for  (int  version  : bco .classHierarchyVersions ){
215+             os .write (bco .classHierarchyVersions .length );
216+             for  (int  version  : bco .classHierarchyVersions )  {
211217                os .write (ByteUtils .convertToBytes (version ));
212218            }
213219            classTableSize  += 1  + bco .classHierarchyVersions .length  * 4 ;
214220
215-             // write classname  size & classname  
221+             // write class name  size & class name  
216222            byte [] classBytes  = key .getBytes ();
217223            os .write (ByteUtils .convertToBytes (classBytes .length )); // 5. "full class-name size" 
218224            os .write (classBytes );                                  // 6. "full class name" 
@@ -236,14 +242,12 @@ public void save(Savable object, OutputStream os) throws IOException {
236242        // write out data to a separate stream 
237243        int  location  = 0 ;
238244        // keep track of location for each piece 
239-         HashMap <String , ArrayList <BinaryIdContentPair >> alreadySaved  = new  HashMap <>(
240-                 contentTable .size ());
245+         HashMap <String , ArrayList <BinaryIdContentPair >> alreadySaved  = new  HashMap <>(contentTable .size ());
241246        for  (Savable  savable  : contentKeys ) {
242247            // look back at previous written data for matches 
243248            String  savableName  = savable .getClass ().getName ();
244249            BinaryIdContentPair  pair  = contentTable .get (savable );
245-             ArrayList <BinaryIdContentPair > bucket  = alreadySaved 
246-                     .get (savableName  + getChunk (pair ));
250+             ArrayList <BinaryIdContentPair > bucket  = alreadySaved .get (savableName  + getChunk (pair ));
247251            int  prevLoc  = findPrevMatch (pair , bucket );
248252            if  (prevLoc  != -1 ) {
249253                locationTable .put (pair .getId (), prevLoc );
@@ -286,17 +290,14 @@ public void save(Savable object, OutputStream os) throws IOException {
286290        // append stream to the output stream 
287291        out .writeTo (os );
288292
289- 
290-         out  = null ;
291-         os  = null ;
292- 
293293        if  (debug ) {
294-             logger .fine ("Stats:" );
295-             logger .log (Level .FINE , "classes: {0}" , classNum );
296-             logger .log (Level .FINE , "class table: {0} bytes" , classTableSize );
297-             logger .log (Level .FINE , "objects: {0}" , numLocations );
298-             logger .log (Level .FINE , "location table: {0} bytes" , locationTableSize );
299-             logger .log (Level .FINE , "data: {0} bytes" , location );
294+             logger .log (Level .INFO , "BinaryExporter Stats:" 
295+                     + "\n  * Classes: {0}" 
296+                     + "\n  * Class Table: {1} bytes" 
297+                     + "\n  * Objects: {2}" 
298+                     + "\n  * Location Table: {3} bytes" 
299+                     + "\n  * Data: {4} bytes" ,
300+                     new  Object [] {classNum , classTableSize , numLocations , locationTableSize , location });
300301        }
301302    }
302303
@@ -305,14 +306,15 @@ private String getChunk(BinaryIdContentPair pair) {
305306                .getContent ().bytes .length ));
306307    }
307308
308-     private  int  findPrevMatch (BinaryIdContentPair  oldPair ,
309-             ArrayList <BinaryIdContentPair > bucket ) {
310-         if  (bucket  == null )
309+     private  int  findPrevMatch (BinaryIdContentPair  oldPair , ArrayList <BinaryIdContentPair > bucket ) {
310+         if  (bucket  == null ) {
311311            return  -1 ;
312+         }
312313        for  (int  x  = bucket .size (); --x  >= 0 ;) {
313314            BinaryIdContentPair  pair  = bucket .get (x );
314-             if  (pair .getContent ().equals (oldPair .getContent ()))
315+             if  (pair .getContent ().equals (oldPair .getContent ())) { 
315316                return  locationTable .get (pair .getId ());
317+             }
316318        }
317319        return  -1 ;
318320    }
@@ -345,7 +347,7 @@ public OutputCapsule getCapsule(Savable object) {
345347        return  contentTable .get (object ).getContent ();
346348    }
347349
348-     private  BinaryClassObject  createClassObject (Class <? extends  Savable > clazz ) throws  IOException {
350+     private  BinaryClassObject  createClassObject (Class <? extends  Savable > clazz ) throws  IOException   {
349351        BinaryClassObject  bco  = new  BinaryClassObject ();
350352        bco .alias  = generateTag ();
351353        bco .nameFields  = new  HashMap <>();
@@ -361,10 +363,10 @@ public int processBinarySavable(Savable object) throws IOException {
361363            return  -1 ;
362364        }
363365        Class <? extends  Savable > clazz  = object .getClass ();
364-         BinaryClassObject  bco  = classes .get (object . getClass () .getName ());
366+         BinaryClassObject  bco  = classes .get (clazz .getName ());
365367        // is this class been looked at before? in tagTable? 
366368        if  (bco  == null ) {
367-             bco  = createClassObject (object . getClass () );
369+             bco  = createClassObject (clazz );
368370        }
369371
370372        // is object in contentTable? 
@@ -379,7 +381,6 @@ public int processBinarySavable(Savable object) throws IOException {
379381        object .write (this );
380382        newPair .getContent ().finish ();
381383        return  newPair .getId ();
382- 
383384    }
384385
385386    protected  byte [] generateTag () {
@@ -401,4 +402,4 @@ private BinaryIdContentPair generateIdContentPair(BinaryClassObject bco) {
401402                new  BinaryOutputCapsule (this , bco ));
402403        return  pair ;
403404    }
404- }
405+ }
0 commit comments