File: gzip_header.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (102 lines) | stat: -rw-r--r-- 3,124 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// The GZipHeader class allows you to parse a gzip header, such as you
// might find at the beginning of a file compressed by gzip (ie, a .gz
// file), or at the beginning of an HTTP response that uses a gzip
// Content-Encoding. See RFC 1952 for the specification for the gzip
// header.
//
// The model is that you call ReadMore() for each chunk of bytes
// you've read from a file or socket.
//

#ifndef NET_FILTER_GZIP_HEADER_H_
#define NET_FILTER_GZIP_HEADER_H_

#include <stddef.h>
#include <stdint.h>

#include "base/containers/span.h"
#include "net/base/net_export.h"

namespace net {

class NET_EXPORT GZipHeader {
 public:
  enum Status {
    INCOMPLETE_HEADER,    // don't have all the bits yet...
    COMPLETE_HEADER,      // complete, valid header
    INVALID_HEADER,       // found something invalid in the header
  };

  GZipHeader();

  GZipHeader(const GZipHeader&) = delete;
  GZipHeader& operator=(const GZipHeader&) = delete;

  ~GZipHeader();

  // Wipe the slate clean and start from scratch.
  void Reset();

  // Attempt to parse the given buffer as the next installment of
  // bytes from a gzip header. If the bytes we've seen so far do not
  // yet constitute a complete gzip header, return
  // INCOMPLETE_HEADER. If these bytes do not constitute a *valid*
  // gzip header, return INVALID_HEADER. When we've seen a complete
  // gzip header, return COMPLETE_HEADER and set `header_end` to the offset
  // of the first byte beyond the gzip header (i.e., it's the number of bytes of
  // `inbuf` the are part of the header).
  Status ReadMore(base::span<const uint8_t> inbuf, size_t& header_end);

  // Returns true if `inbuf` starts with a gzip header, possibly followed by
  // additional bytes.
  static bool HasGZipHeader(base::span<const uint8_t> inbuf);

 private:
  enum {                       // flags (see RFC)
    FLAG_FTEXT        = 0x01,  // bit 0 set: file probably ascii text
    FLAG_FHCRC        = 0x02,  // bit 1 set: header CRC present
    FLAG_FEXTRA       = 0x04,  // bit 2 set: extra field present
    FLAG_FNAME        = 0x08,  // bit 3 set: original file name present
    FLAG_FCOMMENT     = 0x10,  // bit 4 set: file comment present
    FLAG_RESERVED     = 0xE0,  // bits 5..7: reserved
  };

  enum State {
    // The first 10 bytes are the fixed-size header:
    IN_HEADER_ID1,
    IN_HEADER_ID2,
    IN_HEADER_CM,
    IN_HEADER_FLG,
    IN_HEADER_MTIME_BYTE_0,
    IN_HEADER_MTIME_BYTE_1,
    IN_HEADER_MTIME_BYTE_2,
    IN_HEADER_MTIME_BYTE_3,
    IN_HEADER_XFL,
    IN_HEADER_OS,

    IN_XLEN_BYTE_0,
    IN_XLEN_BYTE_1,
    IN_FEXTRA,

    IN_FNAME,

    IN_FCOMMENT,

    IN_FHCRC_BYTE_0,
    IN_FHCRC_BYTE_1,

    IN_DONE,
  };

  int    state_;  // our current State in the parsing FSM: an int so we can ++
  uint8_t flags_;  // the flags byte of the header ("FLG" in the RFC)
  uint16_t extra_length_;  // how much of the "extra field" we have yet to read
};

}  // namespace net

#endif  // NET_FILTER_GZIP_HEADER_H_