simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

decoder.js (1408B)


      1 function con(b) {
      2   if ((b & 0xc0) === 0x80) {
      3     return b & 0x3f;
      4   } else {
      5     throw new Error("invalid UTF-8 encoding");
      6   }
      7 }
      8 
      9 function code(min, n) {
     10   if (n < min || (0xd800 <= n && n < 0xe000) || n >= 0x10000) {
     11     throw new Error("invalid UTF-8 encoding");
     12   } else {
     13     return n;
     14   }
     15 }
     16 
     17 export function decode(bytes) {
     18   return _decode(bytes)
     19     .map(x => String.fromCharCode(x))
     20     .join("");
     21 }
     22 
     23 function _decode(bytes) {
     24   if (bytes.length === 0) {
     25     return [];
     26   }
     27 
     28   /**
     29    * 1 byte
     30    */
     31   {
     32     const [b1, ...bs] = bytes;
     33 
     34     if (b1 < 0x80) {
     35       return [code(0x0, b1), ..._decode(bs)];
     36     }
     37 
     38     if (b1 < 0xc0) {
     39       throw new Error("invalid UTF-8 encoding");
     40     }
     41   }
     42 
     43   /**
     44    * 2 bytes
     45    */
     46   {
     47     const [b1, b2, ...bs] = bytes;
     48 
     49     if (b1 < 0xe0) {
     50       return [code(0x80, ((b1 & 0x1f) << 6) + con(b2)), ..._decode(bs)];
     51     }
     52   }
     53 
     54   /**
     55    * 3 bytes
     56    */
     57   {
     58     const [b1, b2, b3, ...bs] = bytes;
     59 
     60     if (b1 < 0xf0) {
     61       return [
     62         code(0x800, ((b1 & 0x0f) << 12) + (con(b2) << 6) + con(b3)),
     63         ..._decode(bs)
     64       ];
     65     }
     66   }
     67 
     68   /**
     69    * 4 bytes
     70    */
     71   {
     72     const [b1, b2, b3, b4, ...bs] = bytes;
     73 
     74     if (b1 < 0xf8) {
     75       return [
     76         code(
     77           0x10000,
     78           ((((b1 & 0x07) << 18) + con(b2)) << 12) + (con(b3) << 6) + con(b4)
     79         ),
     80         ..._decode(bs)
     81       ];
     82     }
     83   }
     84 
     85   throw new Error("invalid UTF-8 encoding");
     86 }