64 |
64 |
65 class CompressedReadStream : public CompressedStream { |
65 class CompressedReadStream : public CompressedStream { |
66 private: |
66 private: |
67 inline u_char read() { return _buffer[_position++]; } |
67 inline u_char read() { return _buffer[_position++]; } |
68 |
68 |
69 jint read_int_mb(jint b0); // UNSIGNED5 coding, 2-5 byte cases |
69 // This encoding, called UNSIGNED5, is taken from J2SE Pack200. |
|
70 // It assumes that most values have lots of leading zeroes. |
|
71 // Very small values, in the range [0..191], code in one byte. |
|
72 // Any 32-bit value (including negatives) can be coded, in |
|
73 // up to five bytes. The grammar is: |
|
74 // low_byte = [0..191] |
|
75 // high_byte = [192..255] |
|
76 // any_byte = low_byte | high_byte |
|
77 // coding = low_byte |
|
78 // | high_byte low_byte |
|
79 // | high_byte high_byte low_byte |
|
80 // | high_byte high_byte high_byte low_byte |
|
81 // | high_byte high_byte high_byte high_byte any_byte |
|
82 // Each high_byte contributes six bits of payload. |
|
83 // The encoding is one-to-one (except for integer overflow) |
|
84 // and easy to parse and unparse. |
|
85 |
|
86 jint read_int_mb(jint b0) { |
|
87 int pos = position() - 1; |
|
88 u_char* buf = buffer() + pos; |
|
89 assert(buf[0] == b0 && b0 >= L, "correctly called"); |
|
90 jint sum = b0; |
|
91 // must collect more bytes: b[1]...b[4] |
|
92 int lg_H_i = lg_H; |
|
93 for (int i = 0; ; ) { |
|
94 jint b_i = buf[++i]; // b_i = read(); ++i; |
|
95 sum += b_i << lg_H_i; // sum += b[i]*(64**i) |
|
96 if (b_i < L || i == MAX_i) { |
|
97 set_position(pos+i+1); |
|
98 return sum; |
|
99 } |
|
100 lg_H_i += lg_H; |
|
101 } |
|
102 } |
70 |
103 |
71 public: |
104 public: |
72 CompressedReadStream(u_char* buffer, int position = 0) |
105 CompressedReadStream(u_char* buffer, int position = 0) |
73 : CompressedStream(buffer, position) {} |
106 : CompressedStream(buffer, position) {} |
74 |
107 |