001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.msgpack;
014
015import static org.apache.juneau.internal.IOUtils.*;
016import static org.apache.juneau.msgpack.DataType.*;
017
018import java.io.*;
019
020import org.apache.juneau.parser.*;
021
022/**
023 * Specialized input stream for parsing MessagePack streams.
024 *
025 * <h5 class='section'>Notes:</h5>
026 * <ul class='spaced-list'>
027 *    <li>
028 *       This class is not intended for external use.
029 * </ul>
030 */
031public final class MsgPackInputStream extends ParserInputStream {
032
033   private DataType currentDataType;
034   private long length;
035   private int lastByte;
036   private int extType;
037   int pos = 0;
038
039   // Data type quick-lookup table.
040   private static final DataType[] TYPES = new DataType[] {
041      /*0x0?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
042      /*0x1?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
043      /*0x2?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
044      /*0x3?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
045      /*0x4?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
046      /*0x5?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
047      /*0x6?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
048      /*0x7?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
049      /*0x8?*/ MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,MAP,
050      /*0x9?*/ ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,ARRAY,
051      /*0xA?*/ STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,
052      /*0xB?*/ STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,
053      /*0xC?*/ NULL, INVALID, BOOLEAN, BOOLEAN, BIN, BIN, BIN, EXT, EXT, EXT, FLOAT, DOUBLE, INT, INT, LONG, LONG,
054      /*0xD?*/ INT, INT, INT, LONG, EXT, EXT, EXT, EXT, EXT, STRING, STRING, STRING, ARRAY, ARRAY, MAP, MAP,
055      /*0xE?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,
056      /*0xF?*/ INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT,INT
057   };
058
059   /**
060    * Constructor.
061    *
062    * @param pipe The parser input.
063    * @throws Exception
064    */
065   protected MsgPackInputStream(ParserPipe pipe) throws Exception {
066      super(pipe);
067   }
068
069   /**
070    * Reads the data type flag from the stream.
071    *
072    * <p>
073    * This is the byte that indicates what kind of data follows.
074    */
075   DataType readDataType() throws IOException {
076      int i = read();
077      if (i == -1)
078         throw new IOException("Unexpected end of file found at position " + pos);
079      currentDataType = TYPES[i];
080      switch (currentDataType) {
081         case NULL:
082         case FLOAT: {
083            length = 4;
084            break;
085         }
086         case DOUBLE: {
087            length = 8;
088            break;
089         }
090         case BOOLEAN: {
091            lastByte = i;
092            break;
093         }
094         case INT: {
095            // positive fixnum stores 7-bit positive integer
096            // +--------+
097            // |0XXXXXXX|
098            // +--------+
099            //
100            // negative fixnum stores 5-bit negative integer
101            // +--------+
102            // |111YYYYY|
103            // +--------+
104            //
105            // * 0XXXXXXX is 8-bit unsigned integer
106            // * 111YYYYY is 8-bit signed integer
107            //
108            // uint 8 stores a 8-bit unsigned integer
109            // +--------+--------+
110            // |  0xcc  |ZZZZZZZZ|
111            // +--------+--------+
112            //
113            // uint 16 stores a 16-bit big-endian unsigned integer
114            // +--------+--------+--------+
115            // |  0xcd  |ZZZZZZZZ|ZZZZZZZZ|
116            // +--------+--------+--------+
117            //
118            // uint 32 stores a 32-bit big-endian unsigned integer
119            // +--------+--------+--------+--------+--------+
120            // |  0xce  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
121            // +--------+--------+--------+--------+--------+
122            //
123            // uint 64 stores a 64-bit big-endian unsigned integer
124            // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
125            // |  0xcf  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
126            // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
127            //
128            // int 8 stores a 8-bit signed integer
129            // +--------+--------+
130            // |  0xd0  |ZZZZZZZZ|
131            // +--------+--------+
132            //
133            // int 16 stores a 16-bit big-endian signed integer
134            // +--------+--------+--------+
135            // |  0xd1  |ZZZZZZZZ|ZZZZZZZZ|
136            // +--------+--------+--------+
137            //
138            // int 32 stores a 32-bit big-endian signed integer
139            // +--------+--------+--------+--------+--------+
140            // |  0xd2  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
141            // +--------+--------+--------+--------+--------+
142            //
143            // int 64 stores a 64-bit big-endian signed integer
144            // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
145            // |  0xd3  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
146            // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
147            lastByte = i;
148            if (i <= POSFIXINT_U)
149               length = 0;
150            else if (i >= NEGFIXINT_L)
151               length = -1;
152            else if (i == INT8 || i == UINT8)
153               length = 1;
154            else if (i == INT16 || i == UINT16)
155               length = 2;
156            else if (i == INT32)
157               length = 4;
158            else
159               length = 0;
160            break;
161         }
162         case LONG: {
163            if (i == UINT32)
164               length = 4;
165            else if (i == INT64 || i == UINT64)
166               length = 8;
167            else
168               length = 0;
169            break;
170         }
171         case STRING:{
172            // fixstr stores a byte array whose length is up to 31 bytes:
173            // +--------+========+
174            // |101XXXXX|  data  |
175            // +--------+========+
176            //
177            // str 8 stores a byte array whose length is up to (2^8)-1 bytes:
178            // +--------+--------+========+
179            // |  0xd9  |YYYYYYYY|  data  |
180            // +--------+--------+========+
181            //
182            // str 16 stores a byte array whose length is up to (2^16)-1 bytes:
183            // +--------+--------+--------+========+
184            // |  0xda  |ZZZZZZZZ|ZZZZZZZZ|  data  |
185            // +--------+--------+--------+========+
186            //
187            // str 32 stores a byte array whose length is up to (2^32)-1 bytes:
188            // +--------+--------+--------+--------+--------+========+
189            // |  0xdb  |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA|  data  |
190            // +--------+--------+--------+--------+--------+========+
191            //
192            // where
193            // * XXXXX is a 5-bit unsigned integer which represents N
194            // * YYYYYYYY is a 8-bit unsigned integer which represents N
195            // * ZZZZZZZZ_ZZZZZZZZ is a 16-bit big-endian unsigned integer which represents N
196            // * AAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA is a 32-bit big-endian unsigned integer which represents N
197            // * N is the length of data
198            if (i <= FIXSTR_U)
199               length = i & 0x1F;
200            else if (i == STR8)
201               length = readUInt1();
202            else if (i == STR16)
203               length = readUInt2();
204            else
205               length = readUInt4();
206            break;
207         }
208         case ARRAY: {
209            // fixarray stores an array whose length is up to 15 elements:
210            // +--------+~~~~~~~~~~~~~~~~~+
211            // |1001XXXX|    N objects    |
212            // +--------+~~~~~~~~~~~~~~~~~+
213            //
214            // array 16 stores an array whose length is up to (2^16)-1 elements:
215            // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
216            // |  0xdc  |YYYYYYYY|YYYYYYYY|    N objects    |
217            // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
218            //
219            // array 32 stores an array whose length is up to (2^32)-1 elements:
220            // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
221            // |  0xdd  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|    N objects    |
222            // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
223            //
224            // where
225            // * XXXX is a 4-bit unsigned integer which represents N
226            // * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
227            // * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
228            //     N is the size of a array
229            if (i <= FIXARRAY_U)
230               length = i & 0x0F;
231            else if (i == ARRAY16)
232               length = readUInt2();
233            else
234               length = readUInt4();
235            break;
236         }
237         case BIN:{
238            // bin 8 stores a byte array whose length is up to (2^8)-1 bytes:
239            // +--------+--------+========+
240            // |  0xc4  |XXXXXXXX|  data  |
241            // +--------+--------+========+
242            //
243            // bin 16 stores a byte array whose length is up to (2^16)-1 bytes:
244            // +--------+--------+--------+========+
245            // |  0xc5  |YYYYYYYY|YYYYYYYY|  data  |
246            // +--------+--------+--------+========+
247            //
248            // bin 32 stores a byte array whose length is up to (2^32)-1 bytes:
249            // +--------+--------+--------+--------+--------+========+
250            // |  0xc6  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|  data  |
251            // +--------+--------+--------+--------+--------+========+
252            //
253            // where
254            // * XXXXXXXX is a 8-bit unsigned integer which represents N
255            // * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
256            // * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
257            // * N is the length of data
258            if (i == BIN8)
259               length = readUInt1();
260            else if (i == BIN16)
261               length = readUInt2();
262            else
263               length = readUInt4();
264            break;
265         }
266         case EXT:{
267            // fixext 1 stores an integer and a byte array whose length is 1 byte
268            // +--------+--------+--------+
269            // |  0xd4  |  type  |  data  |
270            // +--------+--------+--------+
271            //
272            // fixext 2 stores an integer and a byte array whose length is 2 bytes
273            // +--------+--------+--------+--------+
274            // |  0xd5  |  type  |       data      |
275            // +--------+--------+--------+--------+
276            //
277            // fixext 4 stores an integer and a byte array whose length is 4 bytes
278            // +--------+--------+--------+--------+--------+--------+
279            // |  0xd6  |  type  |                data               |
280            // +--------+--------+--------+--------+--------+--------+
281            //
282            // fixext 8 stores an integer and a byte array whose length is 8 bytes
283            // +--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
284            // |  0xd7  |  type  |                                  data                                 |
285            // +--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
286            //
287            // fixext 16 stores an integer and a byte array whose length is 16 bytes
288            // +--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
289            // |  0xd8  |  type  |                                  data
290            // +--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
291            // +--------+--------+--------+--------+--------+--------+--------+--------+
292            //                               data (cont.)                              |
293            // +--------+--------+--------+--------+--------+--------+--------+--------+
294            //
295            // ext 8 stores an integer and a byte array whose length is up to (2^8)-1 bytes:
296            // +--------+--------+--------+========+
297            // |  0xc7  |XXXXXXXX|  type  |  data  |
298            // +--------+--------+--------+========+
299            //
300            // ext 16 stores an integer and a byte array whose length is up to (2^16)-1 bytes:
301            // +--------+--------+--------+--------+========+
302            // |  0xc8  |YYYYYYYY|YYYYYYYY|  type  |  data  |
303            // +--------+--------+--------+--------+========+
304            //
305            // ext 32 stores an integer and a byte array whose length is up to (2^32)-1 bytes:
306            // +--------+--------+--------+--------+--------+--------+========+
307            // |  0xc9  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|  type  |  data  |
308            // +--------+--------+--------+--------+--------+--------+========+
309            //
310            // where
311            // * XXXXXXXX is a 8-bit unsigned integer which represents N
312            // * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
313            // * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a big-endian 32-bit unsigned integer which represents N
314            // * N is a length of data
315            // * type is a signed 8-bit signed integer
316            // * type < 0 is reserved for future extension including 2-byte type information
317            if (i == FIXEXT1)
318               length = 1;
319            else if (i == FIXEXT2)
320               length = 2;
321            else if (i == FIXEXT4)
322               length = 4;
323            else if (i == FIXEXT8)
324               length = 8;
325            else if (i == FIXEXT16)
326               length = 16;
327            else if (i == EXT8)
328               length = readUInt1();
329            else if (i == EXT16)
330                  length = readUInt2();
331            else if (i == EXT32)
332               length = readUInt4();
333            extType = read();
334
335            break;
336         }
337         case MAP:{
338            // fixmap stores a map whose length is up to 15 elements
339            // +--------+~~~~~~~~~~~~~~~~~+
340            // |1000XXXX|   N*2 objects   |
341            // +--------+~~~~~~~~~~~~~~~~~+
342            //
343            // map 16 stores a map whose length is up to (2^16)-1 elements
344            // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
345            // |  0xde  |YYYYYYYY|YYYYYYYY|   N*2 objects   |
346            // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
347            //
348            // map 32 stores a map whose length is up to (2^32)-1 elements
349            // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
350            // |  0xdf  |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|   N*2 objects   |
351            // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
352            //
353            // where
354            // * XXXX is a 4-bit unsigned integer which represents N
355            // * YYYYYYYY_YYYYYYYY is a 16-bit big-endian unsigned integer which represents N
356            // * ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ_ZZZZZZZZ is a 32-bit big-endian unsigned integer which represents N
357            // * N is the size of a map
358            // * odd elements in objects are keys of a map
359            // * the next element of a key is its associated value
360            if (i <= FIXMAP_U)
361               length = i & 0x0F;
362            else if (i == MAP16)
363               length = readUInt2();
364            else
365               length = readUInt4();
366            break;
367         }
368         default:
369            throw new IOException("Invalid flag 0xC1 detected in stream.");
370      }
371      return currentDataType;
372   }
373
374   /**
375    * Returns the length value for the field.
376    *
377    * <p>
378    * For ints/floats/bins/strings, this is the number of bytes that the field takes up (minus the data-type flag).
379    * For arrays, it's the number of array entries.
380    * For maps, it's the number of map entries.
381    */
382   long readLength() {
383      return length;
384   }
385
386   /**
387    * Read a boolean from the stream.
388    */
389   boolean readBoolean() {
390      return lastByte == TRUE;
391   }
392
393   /**
394    * Read a string from the stream.
395    */
396   String readString() throws IOException {
397      return new String(readBinary(), UTF8);
398   }
399
400   /**
401    * Read a binary field from the stream.
402    */
403   byte[] readBinary() throws IOException {
404      byte[] b = new byte[(int)length];
405      read(b);
406      return b;
407   }
408
409   /**
410    * Read an integer from the stream.
411    */
412   int readInt() throws IOException {
413      if (length == 0)
414         return lastByte;
415      if (length == 1)
416         return read();
417      if (length == 2)
418         return (read() << 8) | read();
419      int i = read(); i <<= 8; i |= read(); i <<= 8; i |= read(); i <<= 8; i |= read();
420      return i;
421   }
422
423   /**
424    * Read a float from the stream.
425    */
426   float readFloat() throws IOException {
427      return Float.intBitsToFloat(readInt());
428   }
429
430   /**
431    * Read a double from the stream.
432    */
433   double readDouble() throws IOException {
434      return Double.longBitsToDouble(readLong());
435   }
436
437   /**
438    * Read 64-bit long from the stream.
439    */
440   long readLong() throws IOException {
441      if (length == 4)
442         return readUInt4();
443      long l = read(); l <<= 8; l |= read(); l <<= 8; l |= read(); l <<= 8; l |= read(); l <<= 8; l |= read(); l <<= 8; l |= read(); l <<= 8; l |= read(); l <<= 8; l |= read();
444      return l;
445   }
446
447   /**
448    * Return the extended-format type.
449    * Currently not used.
450    */
451   int getExtType() {
452      return extType;
453   }
454
455   /**
456    * Read one byte from the stream.
457    */
458   private int readUInt1() throws IOException {
459      return read();
460   }
461
462   /**
463    * Read two bytes from the stream.
464    */
465   private int readUInt2() throws IOException {
466      return (read() << 8) | read();
467   }
468
469   /**
470    * Read four bytes from the stream.
471    */
472   private long readUInt4() throws IOException {
473      long l = read(); l <<= 8; l |= read(); l <<= 8; l |= read(); l <<= 8; l |= read();
474      return l;
475   }
476
477   /**
478    * @deprecated Unused.
479    */
480   @SuppressWarnings("javadoc")
481   @Deprecated
482   public ParserPipe getPipe() {
483      return null;
484   }
485
486   /**
487    * @deprecated Unused.
488    */
489   @Override
490   @Deprecated
491   public int read() throws IOException {
492      return super.read();
493   }
494}