|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "sparse_matmul/zlib_wrapper/gzipheader.h" |
|
|
|
#include <algorithm> |
|
|
|
#include "absl/base/macros.h" |
|
#include "glog/logging.h" |
|
#include "zlib.h" |
|
|
|
namespace csrblocksparse { |
|
|
|
const uint8_t GZipHeader::magic[] = {0x1f, 0x8b}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GZipHeader::Status GZipHeader::ReadMore(const char* inbuf, int inbuf_len, |
|
const char** header_end) { |
|
CHECK_GE(inbuf_len, 0); |
|
const uint8_t* 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 != magic[0]) return INVALID_HEADER; |
|
pos++; |
|
state_++; |
|
break; |
|
case IN_HEADER_ID2: |
|
if (*pos != magic[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; |
|
} |
|
|
|
|
|
extra_length_ = *pos; |
|
pos++; |
|
state_++; |
|
break; |
|
case IN_XLEN_BYTE_1: |
|
extra_length_ += *pos << 8; |
|
pos++; |
|
state_++; |
|
|
|
|
|
ABSL_FALLTHROUGH_INTENDED; |
|
|
|
case IN_FEXTRA: { |
|
|
|
|
|
const int num_extra_bytes = std::min<int>(extra_length_, (end - pos)); |
|
pos += num_extra_bytes; |
|
extra_length_ -= num_extra_bytes; |
|
if (extra_length_ == 0) { |
|
state_ = IN_FNAME; |
|
flags_ &= ~FLAG_FEXTRA; |
|
} |
|
break; |
|
} |
|
|
|
case IN_FNAME: |
|
if (!(flags_ & FLAG_FNAME)) { |
|
state_ = IN_FCOMMENT; |
|
break; |
|
} |
|
|
|
pos = reinterpret_cast<const uint8_t*>(memchr(pos, '\0', (end - pos))); |
|
if (pos != nullptr) { |
|
pos++; |
|
flags_ &= ~FLAG_FNAME; |
|
state_ = IN_FCOMMENT; |
|
} else { |
|
pos = end; |
|
} |
|
break; |
|
|
|
case IN_FCOMMENT: |
|
if (!(flags_ & FLAG_FCOMMENT)) { |
|
state_ = IN_FHCRC_BYTE_0; |
|
break; |
|
} |
|
|
|
pos = reinterpret_cast<const uint8_t*>(memchr(pos, '\0', (end - pos))); |
|
if (pos != nullptr) { |
|
pos++; |
|
flags_ &= ~FLAG_FCOMMENT; |
|
state_ = IN_FHCRC_BYTE_0; |
|
} else { |
|
pos = end; |
|
} |
|
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; |
|
state_++; |
|
break; |
|
|
|
case IN_DONE: |
|
*header_end = reinterpret_cast<const char*>(pos); |
|
return COMPLETE_HEADER; |
|
} |
|
} |
|
|
|
if ((state_ > IN_HEADER_OS) && (flags_ == 0)) { |
|
*header_end = reinterpret_cast<const char*>(pos); |
|
return COMPLETE_HEADER; |
|
} else { |
|
return INCOMPLETE_HEADER; |
|
} |
|
} |
|
|
|
} |
|
|