LCOV - code coverage report
Current view: top level - src - cbor_decoder.dart (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 208 323 64.4 %
Date: 2017-04-06 Functions: 0 0 -

          Line data    Source code
       1             : /*
       2             :  * Package : Cbor
       3             :  * Author : S. Hamblett <steve.hamblett@linux.com>
       4             :  * Date   : 12/12/2016
       5             :  * Copyright :  S.Hamblett
       6             :  */
       7             : 
       8             : part of cbor;
       9             : 
      10             : /// Decoder states
      11             : enum DecoderState {
      12             :   type,
      13             :   pint,
      14             :   nint,
      15             :   bytesSize,
      16             :   bytesData,
      17             :   stringSize,
      18             :   stringData,
      19             :   array,
      20             :   map,
      21             :   tag,
      22             :   special,
      23             :   error
      24             : }
      25             : 
      26             : /// Length constants
      27             : const int oneByte = 1;
      28             : const int twoByte = 2;
      29             : const int fourByte = 4;
      30             : const int eightByte = 8;
      31             : 
      32             : /// The decoder class implements the CBOR decoder functionality as defined in
      33             : /// RFC7049. Output from the decoding process is through the Listener class interface.
      34             : /// Different listener classes can be supplied for different purposes, such as test,
      35             : /// debug as well as the standard stack listener.
      36             : class Decoder {
      37             :   Listener _listener;
      38             :   Input _input;
      39             :   DecoderState _state;
      40             :   int _currentLength;
      41             : 
      42           0 :   Decoder(Input input) {
      43           0 :     _input = input;
      44           0 :     _state = DecoderState.type;
      45             :   }
      46             : 
      47           3 :   Decoder.withListener(Input input, Listener listener) {
      48           3 :     _input = input;
      49           3 :     _state = DecoderState.type;
      50           3 :     _listener = listener;
      51             :   }
      52             : 
      53             :   /// Decoder entry point.
      54             :   void run() {
      55             :     int temp;
      56             :     final bool run = true;
      57             :     while (run) {
      58           6 :       if (_state == DecoderState.type) {
      59           6 :         if (_input.hasBytes(1)) {
      60           6 :           final int type = _input.getByte();
      61           3 :           final int majorType = type >> majorTypeShift;
      62           3 :           final int minorType = type & minorTypeMask;
      63             : 
      64             :           switch (majorType) {
      65           3 :             case majorTypePint: // positive integer
      66           3 :               if (minorType < ai24) {
      67           6 :                 _listener.onInteger(minorType);
      68           3 :               } else if (minorType == ai24) {
      69             :                 // 1 byte
      70           3 :                 _currentLength = oneByte;
      71           3 :                 _state = DecoderState.pint;
      72           3 :               } else if (minorType == ai25) {
      73             :                 // 2 byte
      74           3 :                 _currentLength = twoByte;
      75           3 :                 _state = DecoderState.pint;
      76           3 :               } else if (minorType == ai26) {
      77             :                 // 4 byte
      78           3 :                 _currentLength = fourByte;
      79           3 :                 _state = DecoderState.pint;
      80           1 :               } else if (minorType == ai27) {
      81             :                 // 8 byte
      82           1 :                 _currentLength = eightByte;
      83           1 :                 _state = DecoderState.pint;
      84             :               } else {
      85           0 :                 _state = DecoderState.error;
      86           0 :                 _listener.onError("Decoder::invalid positive integer type");
      87             :               }
      88             :               break;
      89           3 :             case majorTypeNint: // negative integer
      90           3 :               if (minorType < ai24) {
      91           9 :                 _listener.onInteger(-1 - minorType);
      92           3 :               } else if (minorType == ai24) {
      93             :                 // 1 byte
      94           2 :                 _currentLength = oneByte;
      95           2 :                 _state = DecoderState.nint;
      96           3 :               } else if (minorType == ai25) {
      97             :                 // 2 byte
      98           3 :                 _currentLength = twoByte;
      99           3 :                 _state = DecoderState.nint;
     100           2 :               } else if (minorType == ai26) {
     101             :                 // 4 byte
     102           1 :                 _currentLength = fourByte;
     103           1 :                 _state = DecoderState.nint;
     104           1 :               } else if (minorType == ai27) {
     105             :                 // 8 byte
     106           1 :                 _currentLength = eightByte;
     107           1 :                 _state = DecoderState.nint;
     108             :               } else {
     109           0 :                 _state = DecoderState.error;
     110           0 :                 _listener.onError("Decoder::invalid negative integer type");
     111             :               }
     112             :               break;
     113           3 :             case majorTypeBytes: // bytes
     114           3 :               if (minorType < ai24) {
     115           3 :                 _state = DecoderState.bytesData;
     116           3 :                 _currentLength = minorType;
     117           2 :               } else if (minorType == ai24) {
     118           0 :                 _state = DecoderState.bytesSize;
     119           0 :                 _currentLength = oneByte;
     120           2 :               } else if (minorType == ai25) {
     121             :                 // 2 byte
     122           0 :                 _currentLength = twoByte;
     123           0 :                 _state = DecoderState.bytesSize;
     124           2 :               } else if (minorType == ai26) {
     125             :                 // 4 byte
     126           0 :                 _currentLength = fourByte;
     127           0 :                 _state = DecoderState.bytesSize;
     128           2 :               } else if (minorType == ai27) {
     129             :                 // 8 byte
     130           0 :                 _currentLength = eightByte;
     131           0 :                 _state = DecoderState.bytesSize;
     132           2 :               } else if (minorType == aiBreak) {
     133           2 :                 _state = DecoderState.type;
     134           4 :                 _listener.onIndefinite("bytes");
     135             :               } else {
     136           0 :                 _state = DecoderState.error;
     137           0 :                 _listener.onError("Decoder::invalid bytes type");
     138             :               }
     139             :               break;
     140           3 :             case majorTypeString: // string
     141           3 :               if (minorType < ai24) {
     142           3 :                 _state = DecoderState.stringData;
     143           3 :                 _currentLength = minorType;
     144           2 :               } else if (minorType == ai24) {
     145           0 :                 _state = DecoderState.stringSize;
     146           0 :                 _currentLength = oneByte;
     147           2 :               } else if (minorType == ai25) {
     148             :                 // 2 byte
     149           0 :                 _currentLength = twoByte;
     150           0 :                 _state = DecoderState.stringSize;
     151           2 :               } else if (minorType == ai26) {
     152             :                 // 4 byte
     153           0 :                 _currentLength = fourByte;
     154           0 :                 _state = DecoderState.stringSize;
     155           2 :               } else if (minorType == ai27) {
     156             :                 // 8 byte
     157           0 :                 _currentLength = eightByte;
     158           0 :                 _state = DecoderState.stringSize;
     159           2 :               } else if (minorType == aiBreak) {
     160           2 :                 _state = DecoderState.type;
     161           4 :                 _listener.onIndefinite("string");
     162             :               } else {
     163           0 :                 _state = DecoderState.error;
     164           0 :                 _listener.onError("Decoder::invalid string type");
     165             :               }
     166             :               break;
     167           3 :             case majorTypeArray: // array
     168           3 :               if (minorType < ai24) {
     169           6 :                 _listener.onArray(minorType);
     170           2 :               } else if (minorType == ai24) {
     171           1 :                 _state = DecoderState.array;
     172           1 :                 _currentLength = oneByte;
     173           2 :               } else if (minorType == ai25) {
     174             :                 // 2 byte
     175           0 :                 _currentLength = twoByte;
     176           0 :                 _state = DecoderState.array;
     177           2 :               } else if (minorType == ai26) {
     178             :                 // 4 byte
     179           0 :                 _currentLength = fourByte;
     180           0 :                 _state = DecoderState.array;
     181           2 :               } else if (minorType == ai27) {
     182             :                 // 8 byte
     183           0 :                 _currentLength = eightByte;
     184           0 :                 _state = DecoderState.array;
     185           2 :               } else if (minorType == aiBreak) {
     186           2 :                 _state = DecoderState.type;
     187           4 :                 _listener.onIndefinite("array");
     188             :               } else {
     189           0 :                 _state = DecoderState.error;
     190           0 :                 _listener.onError("Decoder::invalid array type");
     191             :               }
     192             :               break;
     193           3 :             case majorTypeMap: // map
     194           3 :               if (minorType < ai24) {
     195           6 :                 _listener.onMap(minorType);
     196           2 :               } else if (minorType == ai24) {
     197           0 :                 _state = DecoderState.map;
     198           0 :                 _currentLength = oneByte;
     199           2 :               } else if (minorType == ai25) {
     200             :                 // 2 byte
     201           0 :                 _currentLength = twoByte;
     202           0 :                 _state = DecoderState.map;
     203           2 :               } else if (minorType == ai26) {
     204             :                 // 4 byte
     205           0 :                 _currentLength = fourByte;
     206           0 :                 _state = DecoderState.map;
     207           2 :               } else if (minorType == ai27) {
     208             :                 // 8 byte
     209           0 :                 _currentLength = eightByte;
     210           0 :                 _state = DecoderState.map;
     211           2 :               } else if (minorType == aiBreak) {
     212           2 :                 _state = DecoderState.type;
     213           4 :                 _listener.onIndefinite("map");
     214             :               } else {
     215           0 :                 _state = DecoderState.error;
     216           0 :                 _listener.onError("Decoder::invalid map type");
     217             :               }
     218             :               break;
     219           3 :             case majorTypeTag: // tag
     220           3 :               if (minorType < ai24) {
     221           6 :                 _listener.onTag(minorType);
     222           3 :               } else if (minorType == ai24) {
     223           3 :                 _state = DecoderState.tag;
     224           3 :                 _currentLength = oneByte;
     225           1 :               } else if (minorType == ai25) {
     226             :                 // 2 byte
     227           1 :                 _currentLength = twoByte;
     228           1 :                 _state = DecoderState.tag;
     229           0 :               } else if (minorType == ai26) {
     230             :                 // 4 byte
     231           0 :                 _currentLength = fourByte;
     232           0 :                 _state = DecoderState.tag;
     233           0 :               } else if (minorType == ai27) {
     234             :                 // 8 byte
     235           0 :                 _currentLength = eightByte;
     236           0 :                 _state = DecoderState.tag;
     237             :               } else {
     238           0 :                 _state = DecoderState.error;
     239           0 :                 _listener.onError("Decoder::invalid tag type");
     240             :               }
     241             :               break;
     242           3 :             case majorTypeSpecial: // special
     243           3 :               if (minorType < ai20) {
     244           6 :                 _listener.onSpecial(minorType);
     245           3 :               } else if (minorType == ai20) {
     246           6 :                 _listener.onBool(false);
     247           3 :               } else if (minorType == ai21) {
     248           6 :                 _listener.onBool(true);
     249           3 :               } else if (minorType == ai22) {
     250           6 :                 _listener.onNull();
     251           3 :               } else if (minorType == ai23) {
     252           6 :                 _listener.onUndefined();
     253           3 :               } else if (minorType == ai24) {
     254           1 :                 _state = DecoderState.special;
     255           1 :                 _currentLength = oneByte;
     256           3 :               } else if (minorType == ai25) {
     257             :                 // 2 byte
     258           3 :                 _currentLength = twoByte;
     259           3 :                 _state = DecoderState.special;
     260           3 :               } else if (minorType == ai26) {
     261             :                 // 4 byte
     262           3 :                 _currentLength = fourByte;
     263           3 :                 _state = DecoderState.special;
     264           3 :               } else if (minorType == ai27) {
     265             :                 // 8 byte
     266           3 :                 _currentLength = eightByte;
     267           3 :                 _state = DecoderState.special;
     268           2 :               } else if (minorType == aiBreak) {
     269           2 :                 _state = DecoderState.type;
     270           4 :                 _listener.onIndefinite("stop");
     271             :               } else {
     272           1 :                 _state = DecoderState.error;
     273           2 :                 _listener.onError("Decoder::invalid special type");
     274             :               }
     275             :               break;
     276             :           }
     277             :         } else
     278             :           break;
     279           6 :       } else if (_state == DecoderState.pint) {
     280           9 :         if (_input.hasBytes(_currentLength)) {
     281           3 :           switch (_currentLength) {
     282           3 :             case 1:
     283          12 :               _listener.onInteger(_input.getByte());
     284           3 :               _state = DecoderState.type;
     285             :               break;
     286           3 :             case 2:
     287          12 :               _listener.onInteger(_input.getShort());
     288           3 :               _state = DecoderState.type;
     289             :               break;
     290           3 :             case 4:
     291           6 :               temp = _input.getInt();
     292           6 :               if (temp <= two32) {
     293           6 :                 _listener.onInteger(temp);
     294             :               } else {
     295           0 :                 _listener.onExtraInteger(temp, 1);
     296             :               }
     297           3 :               _state = DecoderState.type;
     298             :               break;
     299           1 :             case 8:
     300           4 :               _listener.onExtraInteger(_input.getLong(), 1);
     301           1 :               _state = DecoderState.type;
     302             :               break;
     303             :           }
     304             :         } else
     305             :           break;
     306           6 :       } else if (_state == DecoderState.nint) {
     307           9 :         if (_input.hasBytes(_currentLength)) {
     308           3 :           switch (_currentLength) {
     309           3 :             case 1:
     310          10 :               _listener.onInteger(-1 - _input.getByte());
     311           2 :               _state = DecoderState.type;
     312             :               break;
     313           3 :             case 2:
     314          15 :               _listener.onInteger(-1 - _input.getShort());
     315           3 :               _state = DecoderState.type;
     316             :               break;
     317           2 :             case 4:
     318           2 :               temp = _input.getInt();
     319           2 :               if (temp <= two32) {
     320           3 :                 _listener.onInteger(-1 - temp);
     321           0 :               } else if (temp == two32 + 1) {
     322           0 :                 _listener.onInteger(-two32 - 1);
     323             :               } else {
     324           0 :                 _listener.onExtraInteger((-1 - temp), -1);
     325             :               }
     326           1 :               _state = DecoderState.type;
     327             :               break;
     328           1 :             case 8:
     329           5 :               _listener.onExtraInteger((-1 - _input.getLong()), -1);
     330           1 :               _state = DecoderState.type;
     331             :               break;
     332             :           }
     333             :         } else
     334             :           break;
     335           6 :       } else if (_state == DecoderState.bytesSize) {
     336           0 :         if (_input.hasBytes(_currentLength)) {
     337           0 :           switch (_currentLength) {
     338           0 :             case 1:
     339           0 :               _currentLength = _input.getByte();
     340           0 :               _state = DecoderState.bytesData;
     341             :               break;
     342           0 :             case 2:
     343           0 :               _currentLength = _input.getShort();
     344           0 :               _state = DecoderState.bytesData;
     345             :               break;
     346           0 :             case 4:
     347           0 :               _currentLength = _input.getInt();
     348           0 :               _state = DecoderState.bytesData;
     349             :               break;
     350           0 :             case 8:
     351           0 :               _state = DecoderState.error;
     352           0 :               _listener.onError("Decoder::extra long bytes");
     353             :               break;
     354             :           }
     355             :         } else
     356             :           break;
     357           6 :       } else if (_state == DecoderState.bytesData) {
     358           9 :         if (_input.hasBytes(_currentLength)) {
     359             :           typed.Uint8Buffer data;
     360           9 :           data = _input.getBytes(_currentLength);
     361           3 :           _state = DecoderState.type;
     362           9 :           _listener.onBytes(data, _currentLength);
     363             :         } else
     364             :           break;
     365           6 :       } else if (_state == DecoderState.stringSize) {
     366           0 :         if (_input.hasBytes(_currentLength)) {
     367           0 :           switch (_currentLength) {
     368           0 :             case 1:
     369           0 :               _currentLength = _input.getByte();
     370           0 :               _state = DecoderState.stringData;
     371             :               break;
     372           0 :             case 2:
     373           0 :               _currentLength = _input.getShort();
     374           0 :               _state = DecoderState.stringData;
     375             :               break;
     376           0 :             case 4:
     377           0 :               _currentLength = _input.getInt();
     378           0 :               _state = DecoderState.stringData;
     379             :               break;
     380           0 :             case 8:
     381           0 :               _state = DecoderState.error;
     382           0 :               _listener.onError("Decoder::extra long array");
     383             :               break;
     384             :           }
     385             :         } else
     386             :           break;
     387           6 :       } else if (_state == DecoderState.stringData) {
     388           9 :         if (_input.hasBytes(_currentLength)) {
     389             :           typed.Uint8Buffer data;
     390           9 :           data = _input.getBytes(_currentLength);
     391           3 :           final convertor.Utf8Decoder decoder = new convertor.Utf8Decoder();
     392           3 :           final String tmp = decoder.convert(data);
     393           6 :           _listener.onString(tmp);
     394           3 :           _state = DecoderState.type;
     395             :         } else
     396             :           break;
     397           6 :       } else if (_state == DecoderState.array) {
     398           3 :         if (_input.hasBytes(_currentLength)) {
     399           1 :           switch (_currentLength) {
     400           1 :             case 1:
     401           4 :               _listener.onArray(_input.getByte());
     402           1 :               _state = DecoderState.type;
     403             :               break;
     404           0 :             case 2:
     405           0 :               _listener.onArray(_input.getShort());
     406           0 :               _state = DecoderState.type;
     407             :               break;
     408           0 :             case 4:
     409           0 :               _listener.onArray(_input.getInt());
     410           0 :               _state = DecoderState.type;
     411             :               break;
     412           0 :             case 8:
     413           0 :               _state = DecoderState.error;
     414           0 :               _listener.onError("Decoder::extra long array");
     415             :               break;
     416             :           }
     417             :         } else
     418             :           break;
     419           6 :       } else if (_state == DecoderState.map) {
     420           0 :         if (_input.hasBytes(_currentLength)) {
     421           0 :           switch (_currentLength) {
     422           0 :             case 1:
     423           0 :               _listener.onMap(_input.getByte());
     424           0 :               _state = DecoderState.type;
     425             :               break;
     426           0 :             case 2:
     427           0 :               _listener.onMap(_currentLength = _input.getShort());
     428           0 :               _state = DecoderState.type;
     429             :               break;
     430           0 :             case 4:
     431           0 :               _listener.onMap(_input.getInt());
     432           0 :               _state = DecoderState.type;
     433             :               break;
     434           0 :             case 8:
     435           0 :               _state = DecoderState.error;
     436           0 :               _listener.onError("Decoder::extra long map");
     437             :               break;
     438             :           }
     439             :         } else
     440             :           break;
     441           6 :       } else if (_state == DecoderState.tag) {
     442           9 :         if (_input.hasBytes(_currentLength)) {
     443           3 :           switch (_currentLength) {
     444           3 :             case 1:
     445          12 :               _listener.onTag(_input.getByte());
     446           3 :               _state = DecoderState.type;
     447             :               break;
     448           1 :             case 2:
     449           4 :               _listener.onTag(_input.getShort());
     450           1 :               _state = DecoderState.type;
     451             :               break;
     452           0 :             case 4:
     453           0 :               _listener.onTag(_input.getInt());
     454           0 :               _state = DecoderState.type;
     455             :               break;
     456           0 :             case 8:
     457           0 :               _listener.onExtraTag(_input.getLong());
     458           0 :               _state = DecoderState.type;
     459             :               break;
     460             :           }
     461             :         } else
     462             :           break;
     463           6 :       } else if (_state == DecoderState.special) {
     464           9 :         if (_input.hasBytes(_currentLength)) {
     465           3 :           switch (_currentLength) {
     466           3 :             case 1:
     467           4 :               _listener.onSpecial(_input.getByte());
     468           1 :               _state = DecoderState.type;
     469             :               break;
     470           3 :             case 2:
     471           6 :               final int val = _input.getShort();
     472           6 :               final double fval = _input.getHalfFloat(val);
     473           6 :               _listener.onSpecialFloat(fval);
     474           3 :               _state = DecoderState.type;
     475             :               break;
     476           3 :             case 4:
     477           9 :               final typed.Uint8Buffer buff = _input.getBytes(_currentLength);
     478           6 :               final double fval = _input.getSingleFloat(buff);
     479           6 :               _listener.onSpecialFloat(fval);
     480           3 :               _state = DecoderState.type;
     481             :               break;
     482           3 :             case 8:
     483           9 :               final typed.Uint8Buffer buff = _input.getBytes(_currentLength);
     484           6 :               final double fval = _input.getDoubleFloat(buff);
     485           6 :               _listener.onSpecialFloat(fval);
     486           3 :               _state = DecoderState.type;
     487             :               break;
     488             :           }
     489             :         } else
     490             :           break;
     491           2 :       } else if (_state == DecoderState.error) {
     492           2 :         _listener.onError("Decoder::general error");
     493             :         break;
     494             :       } else {
     495           0 :         _listener.onError("Decoder::unknown state");
     496             :       }
     497             :     }
     498             :   }
     499             : 
     500             :   /// Set a listener.
     501             :   void setListener(Listener listenerInstance) {
     502           2 :     _listener = listenerInstance;
     503             :   }
     504             : }

Generated by: LCOV version 1.10