Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(534)

Side by Side Diff: components/safe_browsing_db/v4_rice.cc

Issue 2183433002: PVer4: RICE decode bytes to list of uint32 or 4-byte hash prefixes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tiny: Change the type of data_byte_index_ and current_word_bit_index_ to unsigned int Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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.
4
5 #include "base/logging.h"
6 #include "base/strings/stringprintf.h"
7 #include "components/safe_browsing_db/v4_rice.h"
8
9 namespace safe_browsing {
10
11 namespace {
12
13 const size_t kMaxBitIndex = 8 * sizeof(uint32_t);
14
15 void GetBytesFromUInt32(uint32_t word, char* bytes) {
16 const size_t mask = 0xFF;
17 bytes[0] = (char)(word & mask);
18 bytes[1] = (char)((word >> 8) & mask);
19 bytes[2] = (char)((word >> 16) & mask);
20 bytes[3] = (char)((word >> 24) & mask);
21 }
22
23 } // namespace
24
25 // static
26 V4DecodeResult V4RiceDecoder::DecodeIntegers(const uint32_t first_value,
27 const int32_t rice_parameter,
28 const int32_t num_entries,
29 const std::string& encoded_data,
30 std::vector<uint32_t>* out) {
31 if (!out) {
32 return DECODE_OUTPUT_IS_NULL_FAILURE;
palmer 2016/07/26 23:59:48 Does it make sense to DCHECK here? Well-behaved ca
vakh (use Gerrit instead) 2016/07/27 00:54:33 Done.
33 }
34
35 uint32_t last_value = first_value;
36 out->push_back(last_value);
37 if (num_entries > 0) {
38 V4RiceDecoder decoder(rice_parameter, num_entries, encoded_data);
39 while (decoder.HasAnotherValue()) {
40 uint32_t offset;
41 V4DecodeResult result = decoder.GetNextValue(&offset);
42 if (result != DECODE_SUCCESS) {
43 return result;
44 }
45 last_value += offset;
46 out->push_back(last_value);
47 }
48 }
49 return DECODE_SUCCESS;
50 }
51
52 // static
53 V4DecodeResult V4RiceDecoder::DecodeBytes(const uint32_t first_value,
54 const int32_t rice_parameter,
55 const int32_t num_entries,
56 const std::string& encoded_data,
57 std::string* out) {
58 if (!out) {
59 return DECODE_OUTPUT_IS_NULL_FAILURE;
60 }
61
62 char bytes[4];
63 uint32_t last_value = first_value;
64 GetBytesFromUInt32(last_value, bytes);
65 out->append(bytes);
66 if (num_entries > 0) {
67 V4RiceDecoder decoder(rice_parameter, num_entries, encoded_data);
68 while (decoder.HasAnotherValue()) {
69 uint32_t offset;
70 V4DecodeResult result = decoder.GetNextValue(&offset);
71 if (result != DECODE_SUCCESS) {
72 return result;
73 }
74 last_value += offset;
75
76 GetBytesFromUInt32(last_value, bytes);
77 out->append(bytes);
78 }
79 }
80 return DECODE_SUCCESS;
81 }
82
83 V4RiceDecoder::V4RiceDecoder(const int rice_parameter,
84 const int num_entries,
85 const std::string& encoded_data)
86 : rice_parameter_(rice_parameter),
87 num_entries_(num_entries),
88 data_(encoded_data),
89 current_word_(0) {
90 DCHECK_LE(0, num_entries_);
91 DCHECK_LE(2, rice_parameter_);
92 DCHECK_GE(28, rice_parameter_);
93
94 data_byte_index_ = 0;
95 current_word_bit_index_ = kMaxBitIndex;
96 }
97
98 V4RiceDecoder::~V4RiceDecoder() {}
99
100 bool V4RiceDecoder::HasAnotherValue() const {
101 return num_entries_ > 0;
102 }
103
104 V4DecodeResult V4RiceDecoder::GetNextValue(uint32_t* value) {
105 if (!HasAnotherValue()) {
106 return DECODE_NO_MORE_ENTRIES_FAILURE;
107 }
108
109 V4DecodeResult result;
110 uint32_t q = 0;
111 uint32_t bit;
112 do {
113 result = GetNextBits(1, &bit);
114 if (result != DECODE_SUCCESS) {
115 return result;
116 }
117 q += bit;
118 } while (bit);
119 uint32_t r = 0;
120 result = GetNextBits(rice_parameter_, &r);
121 if (result != DECODE_SUCCESS) {
122 return result;
123 }
124
125 *value = (q << rice_parameter_) + r;
126 num_entries_--;
127 return DECODE_SUCCESS;
128 }
129
130 V4DecodeResult V4RiceDecoder::GetNextWord(uint32_t* word) {
131 if (data_byte_index_ >= data_.size()) {
132 return DECODE_RAN_OUT_OF_BITS_FAILURE;
133 }
134
135 const size_t mask = 0xFF;
136 *word = (data_[data_byte_index_] & mask);
137 data_byte_index_++;
138 current_word_bit_index_ = 0;
139
140 if (data_byte_index_ < data_.size()) {
141 *word |= ((data_[data_byte_index_] & mask) << 8);
142 data_byte_index_++;
143
144 if (data_byte_index_ < data_.size()) {
145 *word |= ((data_[data_byte_index_] & mask) << 16);
146 data_byte_index_++;
147
148 if (data_byte_index_ < data_.size()) {
149 *word |= ((data_[data_byte_index_] & mask) << 24);
150 data_byte_index_++;
151 }
152 }
153 }
154
155 *word = *word & 0xFFFFFFFF;
156 return DECODE_SUCCESS;
157 }
158
159 V4DecodeResult V4RiceDecoder::GetNextBits(size_t num_requested_bits,
160 uint32_t* x) {
161 if (num_requested_bits > kMaxBitIndex) {
162 NOTREACHED();
163 return DECODE_REQUESTED_TOO_MANY_BITS_FAILURE;
164 }
165
166 if (current_word_bit_index_ == kMaxBitIndex) {
167 V4DecodeResult result = GetNextWord(&current_word_);
168 if (result != DECODE_SUCCESS) {
169 return result;
170 }
171 }
172
173 size_t num_bits_left_in_current_word = kMaxBitIndex - current_word_bit_index_;
174 if (num_bits_left_in_current_word >= num_requested_bits) {
175 // All the bits that we need are in current_word_
176 GetBitsFromCurrentWord(num_requested_bits, x);
177 } else {
178 // current_word_ contains fewer bits than we need so we store the current
179 // value of current_word_ in lower, then read in a new current_word_, and
180 // then pick the remaining bits from the new value of current_word_.
181 uint32_t lower = current_word_;
182 // Bits we need after we reading all of current_word_
palmer 2016/07/26 23:59:48 Grammar: "after we read" Style: Mark identifiers w
vakh (use Gerrit instead) 2016/07/27 00:54:33 Done.
183 size_t num_bits_from_next_word =
184 num_requested_bits - num_bits_left_in_current_word;
185 uint32_t upper;
186 V4DecodeResult result = GetNextWord(&current_word_);
187 if (result != DECODE_SUCCESS) {
188 return result;
189 }
190 GetBitsFromCurrentWord(num_bits_from_next_word, &upper);
191 *x = (upper << (num_requested_bits - num_bits_from_next_word)) | lower;
192 }
193 return DECODE_SUCCESS;
194 }
195
196 void V4RiceDecoder::GetBitsFromCurrentWord(size_t num_requested_bits,
197 uint32_t* x) {
198 uint32_t mask = 0xFFFFFFFF >> (kMaxBitIndex - num_requested_bits);
199 *x = current_word_ & mask;
200 current_word_ = current_word_ >> num_requested_bits;
201 current_word_bit_index_ += num_requested_bits;
202 };
203
204 std::string V4RiceDecoder::DebugString() const {
205 return base::StringPrintf(
206 "current_word_: %x; data_byte_index_; %x, "
207 "current_word_bit_index_: %x; rice_parameter_: %x",
208 current_word_, data_byte_index_, current_word_bit_index_,
209 rice_parameter_);
210 }
211
212 std::ostream& operator<<(std::ostream& os, const V4RiceDecoder& rice_decoder) {
213 os << rice_decoder.DebugString();
214 return os;
215 }
216
217 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698