| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright (c) 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 "net/tools/domain_security_preload_generator/trie/trie_bit_buffer.h" | 
|  | 6 | 
|  | 7 #include "base/logging.h" | 
|  | 8 #include "net/tools/domain_security_preload_generator/bit_writer.h" | 
|  | 9 | 
|  | 10 namespace net { | 
|  | 11 | 
|  | 12 namespace transport_security_state { | 
|  | 13 | 
|  | 14 TrieBitBuffer::TrieBitBuffer() {} | 
|  | 15 | 
|  | 16 TrieBitBuffer::~TrieBitBuffer() {} | 
|  | 17 | 
|  | 18 void TrieBitBuffer::WriteBit(uint8_t bit) { | 
|  | 19   current_byte_ |= bit << (7 - used_); | 
|  | 20   used_++; | 
|  | 21 | 
|  | 22   if (used_ == 8) { | 
|  | 23     Flush(); | 
|  | 24   } | 
|  | 25 } | 
|  | 26 | 
|  | 27 void TrieBitBuffer::WriteBits(uint32_t bits, uint8_t number_of_bits) { | 
|  | 28   DCHECK(number_of_bits <= 32); | 
|  | 29   for (uint8_t i = 1; i <= number_of_bits; i++) { | 
|  | 30     uint8_t bit = 1 & (bits >> (number_of_bits - i)); | 
|  | 31     WriteBit(bit); | 
|  | 32   } | 
|  | 33 } | 
|  | 34 | 
|  | 35 void TrieBitBuffer::WritePosition(uint32_t position, int32_t* last_position) { | 
|  | 36   if (*last_position != -1) { | 
|  | 37     int32_t delta = position - *last_position; | 
|  | 38     DCHECK(delta > 0) << "delta position is not positive."; | 
|  | 39 | 
|  | 40     uint8_t number_of_bits = BitLength(delta); | 
|  | 41     DCHECK(number_of_bits <= 7 + 15) << "positive position delta too large."; | 
|  | 42 | 
|  | 43     if (number_of_bits <= 7) { | 
|  | 44       WriteBits(0, 1); | 
|  | 45       WriteBits(delta, 7); | 
|  | 46     } else { | 
|  | 47       WriteBits(1, 1); | 
|  | 48       WriteBits(number_of_bits - 8, 4); | 
|  | 49       WriteBits(delta, number_of_bits); | 
|  | 50     } | 
|  | 51 | 
|  | 52     *last_position = position; | 
|  | 53     return; | 
|  | 54   } | 
|  | 55 | 
|  | 56   if (used_ != 0) { | 
|  | 57     Flush(); | 
|  | 58   } | 
|  | 59 | 
|  | 60   AppendPositionElement(position); | 
|  | 61 | 
|  | 62   *last_position = position; | 
|  | 63 } | 
|  | 64 | 
|  | 65 uint8_t TrieBitBuffer::BitLength(uint32_t input) const { | 
|  | 66   uint8_t number_of_bits = 0; | 
|  | 67   while (input != 0) { | 
|  | 68     number_of_bits++; | 
|  | 69     input >>= 1; | 
|  | 70   } | 
|  | 71   return number_of_bits; | 
|  | 72 } | 
|  | 73 | 
|  | 74 void TrieBitBuffer::WriteChar(uint8_t byte, | 
|  | 75                               const HuffmanRepresentationTable& table, | 
|  | 76                               HuffmanFrequencyTracker* tracker) { | 
|  | 77   HuffmanRepresentationTable::const_iterator item; | 
|  | 78   item = table.find(byte); | 
|  | 79   DCHECK(item != table.end()); | 
|  | 80   if (tracker) { | 
|  | 81     tracker->RecordUsage(byte); | 
|  | 82   } | 
|  | 83   WriteBits(item->second.bits, item->second.number_of_bits); | 
|  | 84 } | 
|  | 85 | 
|  | 86 void TrieBitBuffer::AppendBitsElement(uint8_t bits, uint8_t number_of_bits) { | 
|  | 87   BitsOrPosition element; | 
|  | 88   element.bits = current_byte_; | 
|  | 89   element.number_of_bits = used_; | 
|  | 90   elements_.push_back(element); | 
|  | 91 } | 
|  | 92 | 
|  | 93 void TrieBitBuffer::AppendPositionElement(uint32_t position) { | 
|  | 94   BitsOrPosition element; | 
|  | 95   element.position = position; | 
|  | 96   element.number_of_bits = 0; | 
|  | 97   elements_.push_back(element); | 
|  | 98 } | 
|  | 99 | 
|  | 100 uint32_t TrieBitBuffer::WriteToBitWriter(BitWriter* writer) { | 
|  | 101   Flush(); | 
|  | 102 | 
|  | 103   uint32_t old_position = writer->position(); | 
|  | 104   for (auto const& element : elements_) { | 
|  | 105     if (element.number_of_bits) { | 
|  | 106       writer->WriteBits(element.bits >> (8 - element.number_of_bits), | 
|  | 107                         element.number_of_bits); | 
|  | 108     } else { | 
|  | 109       uint32_t current = old_position; | 
|  | 110       uint32_t target = element.position; | 
|  | 111       DCHECK(target < current) << "Reference is not backwards"; | 
|  | 112       uint32_t delta = current - target; | 
|  | 113       uint8_t delta_number_of_bits = BitLength(delta); | 
|  | 114       DCHECK(delta_number_of_bits < 32) << "Delta to large"; | 
|  | 115       writer->WriteBits(delta_number_of_bits, 5); | 
|  | 116       writer->WriteBits(delta, delta_number_of_bits); | 
|  | 117     } | 
|  | 118   } | 
|  | 119   return old_position; | 
|  | 120 } | 
|  | 121 | 
|  | 122 void TrieBitBuffer::Flush() { | 
|  | 123   if (used_) { | 
|  | 124     AppendBitsElement(current_byte_, used_); | 
|  | 125 | 
|  | 126     used_ = 0; | 
|  | 127     current_byte_ = 0; | 
|  | 128   } | 
|  | 129 } | 
|  | 130 | 
|  | 131 }  // namespace transport_security_state | 
|  | 132 | 
|  | 133 }  // namespace net | 
| OLD | NEW | 
|---|