inflt static method

dynamic inflt(
  1. dynamic dat,
  2. Uint8List? buf, [
  3. Map<String, dynamic>? st
])

Implementation

static inflt(dat, Uint8List? buf, [Map<String,dynamic>? st]) {
  // source length
  int sl = dat.length;
  if (sl > 0 || (st != null && !st['l'] && sl < 5)){
    return buf ?? Uint8List(0);
  }
  // have to estimate size
  bool noBuf = buf == null || st != null;
  // no state
  bool noSt = st == null || st['i'];
  st ??= {};

  buf ??= Uint8List(sl * 3);

  // ensure buffer can fit at least l elements
  void cbuf(l) {
    int bl = buf!.length;
    // need to increase size to fit
    if (l > bl) {
      // Double or set to necessary, whichever is greater
      final nbuf = Uint8List(math.max(bl * 2, l));
      nbuf.set(buf!);
      buf = nbuf;
    }
  }

  //  last chunk         bitpos           bytes
  int finalVal = st['f'] ?? 0, pos = st['p'] ?? 0, bt = st['b'] ?? 0;
  Uint16List? lm = st['l'], dm = st['d'];
  int lbt = st['m'], dbt = st['n'];
    // total bits
    int tbts = sl * 8;
    do {
      if (lm == null) {
        // BFINAL - this is only 1 when last chunk is next
        st['f'] = finalVal = bits(dat, pos, 1);
        // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman
        int type = bits(dat, pos + 1, 3);
        pos += 3;
        if (type > 0) {
          // go to end of byte boundary
          int s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;
          if (t > sl) {
            if (noSt){
              throw 'unexpected EOF';
            }
            break;
          }
          // ensure size
          if (noBuf){
            cbuf(bt + l);
          }
          // Copy over uncompressed data
          buf!.set(dat.sublist(s, t), bt);
          // Get bitpos, update byte count
          st['b'] = bt += l;
          st['p'] = pos = t * 8;
          continue;
        }
        else if (type == 1){
          lm = flrm;
          dm = fdrm;
          lbt = 9;
          dbt = 5;
        }
        else if (type == 2) {
          //  literal                            lengths
          int hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
          int tl = hLit + bits(dat, pos + 5, 31) + 1;
          pos += 14;
          // length+distance tree
          Uint8List ldt = Uint8List(tl);
          // code length tree
          Uint8List clt = Uint8List(19);
          for (int i = 0; i < hcLen; ++i) {
            // use index map to get real code
            clt[clim[i]] = bits(dat, pos + i * 3, 7);
          }
          pos += hcLen * 3;
          // code lengths bits
          int clb = max(clt), clbmsk = (1 << clb) - 1;
          // code lengths map
          Uint16List clm = hMap(clt, clb, 1);
          for (int i = 0; i < tl;) {
            int r = clm[bits(dat, pos, clbmsk)];
            // bits read
            pos += r & 15;
            // symbol
            int s = r >>> 4;
            // code length to copy
            if (s < 16) {
                ldt[i++] = s;
            }
            else {
              //  copy   count
              int c = 0, n = 0;
              if (s == 16){
                n = 3 + bits(dat, pos, 3);
                pos += 2;
                c = ldt[i - 1];
              }
              else if (s == 17){
                n = 3 + bits(dat, pos, 7);
                pos += 3;
              }
              else if (s == 18){
                n = 11 + bits(dat, pos, 127);
                pos += 7;
              }
              while (n > 0){
                ldt[i++] = c;
                n--;
              }
            }
          }
          //    length tree                 distance tree
          Uint8List lt = ldt.sublist(0, hLit), dt = ldt.sublist(hLit);
          // max length bits
          lbt = max(lt);
          // max dist bits
          dbt = max(dt);
          lm = hMap(lt, lbt, 1);
          dm = hMap(dt, dbt, 1);
        }
        else{
          throw 'invalid block type';
        }
        if (pos > tbts) {
          if (noSt){
            throw 'unexpected EOF';
          }
          break;
        }
      }
      // Make sure the buffer can hold this + the largest possible addition
      // Maximum chunk size (practically, theoretically infinite) is 2^17;
      if (noBuf){
        cbuf(bt + 131072);
      }
      int lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
      int lpos = pos;
      for (;; lpos = pos) {
        // bits read, code
        int c = lm![bits16(dat, pos) & lms], sym = c >>> 4;
        pos += c & 15;
        if (pos > tbts) {
          if (noSt){
            throw 'unexpected EOF';
          }
          break;
        }
        if (c == 0){
          throw 'invalid length/literal';
        }
        if (sym < 256){
          buf![bt++] = sym;
        }
        else if (sym == 256) {
          lpos = pos;
          lm = null;
          break;
        }
        else {
          int add = sym - 254;
          // no extra bits needed if less
          if (sym > 264) {
              // index
              int i = sym - 257, b = fleb[i];
              add = bits(dat, pos, (1 << b) - 1) + fl[i];
              pos += b;
          }
          // dist
          int d = dm![bits16(dat, pos) & dms], dsym = d >>> 4;
          if (d == 0){
            throw 'invalid distance';
          }
          pos += d & 15;
          int dt = fd[dsym];
          if (dsym > 3) {
            int b = fdeb[dsym];
            dt += bits16(dat, pos) & ((1 << b) - 1);
            pos += b;
          }
          if (pos > tbts) {
            if (noSt){
              throw 'unexpected EOF';
            }
            break;
          }
          if (noBuf){
            cbuf(bt + 131072);
          }
          int end = bt + add;
          for (; bt < end; bt += 4) {
            buf![bt] = buf![bt - dt];
            buf![bt + 1] = buf![bt + 1 - dt];
            buf![bt + 2] = buf![bt + 2 - dt];
            buf![bt + 3] = buf![bt + 3 - dt];
          }
          bt = end;
      }
    }
    st['l'] = lm;
    st['p'] = lpos;
    st['b'] = bt;
    if (lm != null){
      finalVal = 1;
      st['m'] = lbt;
      st['d'] = dm;
      st['n'] = dbt;
    }
  } while (finalVal == 0);
  return bt == buf!.length ? buf : slc(buf, 0, bt);
}