1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/base/gzip_header.h"
7 #if defined(USE_SYSTEM_ZLIB)
10 #include "third_party/zlib/zlib.h" // for Z_DEFAULT_COMPRESSION
13 #include "base/logging.h"
17 const uint8
GZipHeader::magic
[] = { 0x1f, 0x8b };
19 GZipHeader::GZipHeader() {
23 GZipHeader::~GZipHeader() {
26 void GZipHeader::Reset() {
27 state_
= IN_HEADER_ID1
;
32 GZipHeader::Status
GZipHeader::ReadMore(const char* inbuf
, int inbuf_len
,
33 const char** header_end
) {
34 DCHECK_GE(inbuf_len
, 0);
35 const uint8
* pos
= reinterpret_cast<const uint8
*>(inbuf
);
36 const uint8
* const end
= pos
+ inbuf_len
;
41 if ( *pos
!= magic
[0] ) return INVALID_HEADER
;
46 if ( *pos
!= magic
[1] ) return INVALID_HEADER
;
51 if ( *pos
!= Z_DEFLATED
) return INVALID_HEADER
;
56 flags_
= (*pos
) & (FLAG_FHCRC
| FLAG_FEXTRA
|
57 FLAG_FNAME
| FLAG_FCOMMENT
);
62 case IN_HEADER_MTIME_BYTE_0
:
66 case IN_HEADER_MTIME_BYTE_1
:
70 case IN_HEADER_MTIME_BYTE_2
:
74 case IN_HEADER_MTIME_BYTE_3
:
90 if ( !(flags_
& FLAG_FEXTRA
) ) {
94 // We have a two-byte little-endian length, followed by a
95 // field of that length.
101 extra_length_
+= *pos
<< 8;
104 // We intentionally fall through, because if we have a
105 // zero-length FEXTRA, we want to check to notice that we're
106 // done reading the FEXTRA before we exit this loop...
109 // Grab the rest of the bytes in the extra field, or as many
110 // of them as are actually present so far.
111 const int num_extra_bytes
= static_cast<const int>(std::min(
112 static_cast<ptrdiff_t>(extra_length_
),
114 pos
+= num_extra_bytes
;
115 extra_length_
-= num_extra_bytes
;
116 if ( extra_length_
== 0 ) {
117 state_
= IN_FNAME
; // advance when we've seen extra_length_ bytes
118 flags_
&= ~FLAG_FEXTRA
; // we're done with the FEXTRA stuff
124 if ( !(flags_
& FLAG_FNAME
) ) {
125 state_
= IN_FCOMMENT
;
128 // See if we can find the end of the \0-terminated FNAME field.
129 pos
= reinterpret_cast<const uint8
*>(memchr(pos
, '\0', (end
- pos
)));
131 pos
++; // advance past the '\0'
132 flags_
&= ~FLAG_FNAME
; // we're done with the FNAME stuff
133 state_
= IN_FCOMMENT
;
135 pos
= end
; // everything we have so far is part of the FNAME
140 if ( !(flags_
& FLAG_FCOMMENT
) ) {
141 state_
= IN_FHCRC_BYTE_0
;
144 // See if we can find the end of the \0-terminated FCOMMENT field.
145 pos
= reinterpret_cast<const uint8
*>(memchr(pos
, '\0', (end
- pos
)));
147 pos
++; // advance past the '\0'
148 flags_
&= ~FLAG_FCOMMENT
; // we're done with the FCOMMENT stuff
149 state_
= IN_FHCRC_BYTE_0
;
151 pos
= end
; // everything we have so far is part of the FNAME
155 case IN_FHCRC_BYTE_0
:
156 if ( !(flags_
& FLAG_FHCRC
) ) {
164 case IN_FHCRC_BYTE_1
:
166 flags_
&= ~FLAG_FHCRC
; // we're done with the FHCRC stuff
171 *header_end
= reinterpret_cast<const char*>(pos
);
172 return COMPLETE_HEADER
;
176 if ( (state_
> IN_HEADER_OS
) && (flags_
== 0) ) {
177 *header_end
= reinterpret_cast<const char*>(pos
);
178 return COMPLETE_HEADER
;
180 return INCOMPLETE_HEADER
;