GZipHeader::Status GZipHeader::ReadMore()

in tensorflow_serving/util/net_http/compression/gzip_zlib.cc [50:201]


GZipHeader::Status GZipHeader::ReadMore(const char *inbuf, int inbuf_len,
                                        const char **header_end) {
  auto pos = reinterpret_cast<const uint8_t *>(inbuf);
  const uint8_t *const end = pos + inbuf_len;

  while (pos < end) {
    switch (state_) {
      case IN_HEADER_ID1:
        if (*pos != kMagicHeader[0]) return INVALID_HEADER;
        pos++;
        state_++;
        break;
      case IN_HEADER_ID2:
        if (*pos != kMagicHeader[1]) return INVALID_HEADER;
        pos++;
        state_++;
        break;
      case IN_HEADER_CM:
        if (*pos != Z_DEFLATED) return INVALID_HEADER;
        pos++;
        state_++;
        break;
      case IN_HEADER_FLG:
        flags_ =
            (*pos) & (FLAG_FHCRC | FLAG_FEXTRA | FLAG_FNAME | FLAG_FCOMMENT);
        pos++;
        state_++;
        break;

      case IN_HEADER_MTIME_BYTE_0:
        pos++;
        state_++;
        break;
      case IN_HEADER_MTIME_BYTE_1:
        pos++;
        state_++;
        break;
      case IN_HEADER_MTIME_BYTE_2:
        pos++;
        state_++;
        break;
      case IN_HEADER_MTIME_BYTE_3:
        pos++;
        state_++;
        break;

      case IN_HEADER_XFL:
        pos++;
        state_++;
        break;

      case IN_HEADER_OS:
        pos++;
        state_++;
        break;

      case IN_XLEN_BYTE_0:
        if (!(flags_ & FLAG_FEXTRA)) {
          state_ = IN_FNAME;
          break;
        }
        // We have a two-byte little-endian length, followed by a
        // field of that length.
        extra_length_ = *pos;
        pos++;
        state_++;
        break;
      case IN_XLEN_BYTE_1:
        extra_length_ += (*pos) << 8;
        pos++;
        state_++;
        ABSL_FALLTHROUGH_INTENDED;
        // if we have a zero-length FEXTRA, we want to check
        // to notice that we're done reading the FEXTRA before we exit the loop.

      case IN_FEXTRA: {
        // Grab the rest of the bytes in the extra field, or as many
        // of them as are actually present so far.
        const int num_extra_bytes =
            std::min<int>(extra_length_, absl::implicit_cast<int>(end - pos));
        pos += num_extra_bytes;
        extra_length_ -= num_extra_bytes;
        if (extra_length_ == 0) {
          state_ = IN_FNAME;  // advance when we've seen extra_length_ bytes
          flags_ &= ~FLAG_FEXTRA;  // we're done with the FEXTRA stuff
        }
        break;
      }

      case IN_FNAME:
        if (!(flags_ & FLAG_FNAME)) {
          state_ = IN_FCOMMENT;
          break;
        }
        // See if we can find the end of the \0-terminated FNAME field.
        pos = reinterpret_cast<const uint8_t *>(memchr(pos, '\0', (end - pos)));
        if (pos != nullptr) {
          pos++;                  // advance past the '\0'
          flags_ &= ~FLAG_FNAME;  // we're done with the FNAME stuff
          state_ = IN_FCOMMENT;
        } else {
          pos = end;  // everything we have so far is part of the FNAME
        }
        break;

      case IN_FCOMMENT:
        if (!(flags_ & FLAG_FCOMMENT)) {
          state_ = IN_FHCRC_BYTE_0;
          break;
        }
        // See if we can find the end of the \0-terminated FCOMMENT field.
        pos = reinterpret_cast<const uint8_t *>(memchr(pos, '\0', (end - pos)));
        if (pos != nullptr) {
          pos++;                     // advance past the '\0'
          flags_ &= ~FLAG_FCOMMENT;  // we're done with the FCOMMENT stuff
          state_ = IN_FHCRC_BYTE_0;
        } else {
          pos = end;  // everything we have so far is part of the FNAME
        }
        break;

      case IN_FHCRC_BYTE_0:
        if (!(flags_ & FLAG_FHCRC)) {
          state_ = IN_DONE;
          break;
        }
        pos++;
        state_++;
        break;

      case IN_FHCRC_BYTE_1:
        pos++;
        flags_ &= ~FLAG_FHCRC;  // we're done with the FHCRC stuff
        state_++;
        break;

      case IN_DONE:
        *header_end = reinterpret_cast<const char *>(pos);
        return COMPLETE_HEADER;

      default:
        break;
    }
  }

  if ((state_ > IN_HEADER_OS) && (flags_ == 0)) {
    *header_end = reinterpret_cast<const char *>(pos);
    return COMPLETE_HEADER;
  } else {
    return INCOMPLETE_HEADER;
  }
}