Adds a reset button to the zoom bubble on GTK.
[chromium-blink-merge.git] / net / base / gzip_header.cc
blob23a3dd3eb1127bf491bc99851cbe58e9a5b77286
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)
8 #include <zlib.h>
9 #else
10 #include "third_party/zlib/zlib.h" // for Z_DEFAULT_COMPRESSION
11 #endif
13 #include "base/logging.h"
15 namespace net {
17 const uint8 GZipHeader::magic[] = { 0x1f, 0x8b };
19 GZipHeader::GZipHeader() {
20 Reset();
23 GZipHeader::~GZipHeader() {
26 void GZipHeader::Reset() {
27 state_ = IN_HEADER_ID1;
28 flags_ = 0;
29 extra_length_ = 0;
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;
38 while ( pos < end ) {
39 switch ( state_ ) {
40 case IN_HEADER_ID1:
41 if ( *pos != magic[0] ) return INVALID_HEADER;
42 pos++;
43 state_++;
44 break;
45 case IN_HEADER_ID2:
46 if ( *pos != magic[1] ) return INVALID_HEADER;
47 pos++;
48 state_++;
49 break;
50 case IN_HEADER_CM:
51 if ( *pos != Z_DEFLATED ) return INVALID_HEADER;
52 pos++;
53 state_++;
54 break;
55 case IN_HEADER_FLG:
56 flags_ = (*pos) & (FLAG_FHCRC | FLAG_FEXTRA |
57 FLAG_FNAME | FLAG_FCOMMENT);
58 pos++;
59 state_++;
60 break;
62 case IN_HEADER_MTIME_BYTE_0:
63 pos++;
64 state_++;
65 break;
66 case IN_HEADER_MTIME_BYTE_1:
67 pos++;
68 state_++;
69 break;
70 case IN_HEADER_MTIME_BYTE_2:
71 pos++;
72 state_++;
73 break;
74 case IN_HEADER_MTIME_BYTE_3:
75 pos++;
76 state_++;
77 break;
79 case IN_HEADER_XFL:
80 pos++;
81 state_++;
82 break;
84 case IN_HEADER_OS:
85 pos++;
86 state_++;
87 break;
89 case IN_XLEN_BYTE_0:
90 if ( !(flags_ & FLAG_FEXTRA) ) {
91 state_ = IN_FNAME;
92 break;
94 // We have a two-byte little-endian length, followed by a
95 // field of that length.
96 extra_length_ = *pos;
97 pos++;
98 state_++;
99 break;
100 case IN_XLEN_BYTE_1:
101 extra_length_ += *pos << 8;
102 pos++;
103 state_++;
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...
108 case IN_FEXTRA: {
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_),
113 (end - pos)));
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
120 break;
123 case IN_FNAME:
124 if ( !(flags_ & FLAG_FNAME) ) {
125 state_ = IN_FCOMMENT;
126 break;
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)));
130 if ( pos != NULL ) {
131 pos++; // advance past the '\0'
132 flags_ &= ~FLAG_FNAME; // we're done with the FNAME stuff
133 state_ = IN_FCOMMENT;
134 } else {
135 pos = end; // everything we have so far is part of the FNAME
137 break;
139 case IN_FCOMMENT:
140 if ( !(flags_ & FLAG_FCOMMENT) ) {
141 state_ = IN_FHCRC_BYTE_0;
142 break;
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)));
146 if ( pos != NULL ) {
147 pos++; // advance past the '\0'
148 flags_ &= ~FLAG_FCOMMENT; // we're done with the FCOMMENT stuff
149 state_ = IN_FHCRC_BYTE_0;
150 } else {
151 pos = end; // everything we have so far is part of the FNAME
153 break;
155 case IN_FHCRC_BYTE_0:
156 if ( !(flags_ & FLAG_FHCRC) ) {
157 state_ = IN_DONE;
158 break;
160 pos++;
161 state_++;
162 break;
164 case IN_FHCRC_BYTE_1:
165 pos++;
166 flags_ &= ~FLAG_FHCRC; // we're done with the FHCRC stuff
167 state_++;
168 break;
170 case IN_DONE:
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;
179 } else {
180 return INCOMPLETE_HEADER;
184 } // namespace net