1111import java .nio .ByteOrder ;
1212import java .nio .charset .StandardCharsets ;
1313import java .text .ParseException ;
14+ import java .util .ArrayDeque ;
1415import java .util .ArrayList ;
15- import java .util .Stack ;
16- import java .util .function .Function ;
16+ import java .util .Deque ;
1717
1818import com .fasterxml .jackson .core .JsonFactory ;
1919import com .fasterxml .jackson .core .JsonParseException ;
@@ -25,9 +25,8 @@ public class DsonWriter {
2525 HeaderBlock header ;
2626 ByteArrayOutputStream data ;
2727 ArrayList <Meta1BlockEntry > meta1Entries ;
28- // Stack over Deque for random access .get
29- Stack <Integer > hierarchyHintStack ;
30- Stack <String > nameStack ;
28+ Deque <Integer > hierarchyHintStack ;
29+ Deque <String > nameStack ;
3130 ArrayList <Meta2BlockEntry > meta2Entries ;
3231
3332 public DsonWriter (String jsonData ) throws IOException , ParseException {
@@ -47,8 +46,8 @@ private DsonWriter(JsonParser reader) throws IOException, ParseException {
4746
4847 meta1Entries = new ArrayList <>();
4948 meta2Entries = new ArrayList <>();
50- hierarchyHintStack = new Stack <>();
51- nameStack = new Stack <>();
49+ hierarchyHintStack = new ArrayDeque <>();
50+ nameStack = new ArrayDeque <>();
5251 hierarchyHintStack .push (-1 );
5352
5453 try {
@@ -92,9 +91,7 @@ private void writeField(String name, JsonParser reader) throws IOException, Pars
9291 e2 .offset = data .size ();
9392 data .write (name .getBytes (StandardCharsets .UTF_8 ));
9493 data .write (0 );
95-
96- Function <Integer , String > nameMapper = (i ) -> i == 0 ? name
97- : (i <= nameStack .size () ? nameStack .get (nameStack .size () - i ) : null );
94+
9895 try {
9996 reader .nextToken ();
10097 if (reader .getCurrentToken () == JsonToken .START_OBJECT ) {
@@ -137,7 +134,9 @@ private void writeField(String name, JsonParser reader) throws IOException, Pars
137134 } else {
138135 // Now for the tricky part: Not an object, now we need to determine the type
139136 // Same as in DsonField, we first check the hardcoded types
140- if (DsonTypes .isA (FieldType .TYPE_FLOATARRAY , nameMapper )) {
137+ // In order to easily use the nameStack's iterator, we temporarily push the field name
138+ nameStack .push (name );
139+ if (DsonTypes .isA (FieldType .TYPE_FLOATARRAY , nameStack ::iterator )) {
141140 align ();
142141 if (reader .getCurrentToken () != JsonToken .START_ARRAY ) {
143142 throw new ParseException ("Expected START_ARRAY" ,
@@ -150,7 +149,7 @@ private void writeField(String name, JsonParser reader) throws IOException, Pars
150149 throw new ParseException ("Expected VALUE_NUMBER_FLOAT or END_ARRAY" ,
151150 (int ) reader .getCurrentLocation ().getCharOffset ());
152151 }
153- } else if (DsonTypes .isA (FieldType .TYPE_INTVECTOR , nameMapper )) {
152+ } else if (DsonTypes .isA (FieldType .TYPE_INTVECTOR , nameStack :: iterator )) {
154153 align ();
155154 if (reader .getCurrentToken () != JsonToken .START_ARRAY ) {
156155 throw new ParseException ("Expected START_ARRAY" ,
@@ -177,7 +176,7 @@ private void writeField(String name, JsonParser reader) throws IOException, Pars
177176 }
178177 data .write (intBytes (numElem ));
179178 data .write (vecData .toByteArray ());
180- } else if (DsonTypes .isA (FieldType .TYPE_STRINGVECTOR , nameMapper )) {
179+ } else if (DsonTypes .isA (FieldType .TYPE_STRINGVECTOR , nameStack :: iterator )) {
181180 align ();
182181 if (reader .getCurrentToken () != JsonToken .START_ARRAY ) {
183182 throw new ParseException ("Expected START_ARRAY" ,
@@ -187,6 +186,7 @@ private void writeField(String name, JsonParser reader) throws IOException, Pars
187186 int numElem = 0 ;
188187 while (reader .nextToken () == JsonToken .VALUE_STRING ) {
189188 numElem += 1 ;
189+ vecData .write (new byte [(4 - (vecData .size () % 4 )) % 4 ]);
190190 vecData .write (stringBytes (reader .getValueAsString ()));
191191 }
192192 if (reader .getCurrentToken () != JsonToken .END_ARRAY ) {
@@ -195,14 +195,14 @@ private void writeField(String name, JsonParser reader) throws IOException, Pars
195195 }
196196 data .write (intBytes (numElem ));
197197 data .write (vecData .toByteArray ());
198- } else if (DsonTypes .isA (FieldType .TYPE_FLOAT , nameMapper )) {
198+ } else if (DsonTypes .isA (FieldType .TYPE_FLOAT , nameStack :: iterator )) {
199199 align ();
200200 if (reader .getCurrentToken () != JsonToken .VALUE_NUMBER_FLOAT ) {
201201 throw new ParseException ("Expected VALUE_NUMBER_FLOAT" ,
202202 (int ) reader .getCurrentLocation ().getCharOffset ());
203203 }
204204 data .write (floatBytes (reader .getFloatValue ()));
205- } else if (DsonTypes .isA (FieldType .TYPE_CHAR , nameMapper )) {
205+ } else if (DsonTypes .isA (FieldType .TYPE_CHAR , nameStack :: iterator )) {
206206 if (reader .getCurrentToken () != JsonToken .VALUE_STRING ) {
207207 throw new ParseException (
208208 name + ": Expected VALUE_STRING, got " + reader .getCurrentToken ().asString (),
@@ -238,6 +238,7 @@ private void writeField(String name, JsonParser reader) throws IOException, Pars
238238 throw new ParseException ("Field " + name + " not identified" ,
239239 (int ) reader .getCurrentLocation ().getCharOffset ());
240240 }
241+ nameStack .pop ();
241242 }
242243 } catch (ClassCastException | IllegalStateException e ) {
243244 throw new ParseException ("Error writing " + name , (int ) reader .getCurrentLocation ().getCharOffset ());
0 commit comments