Home | History | Annotate | Download | only in src
      1 // Copyright 2014 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 // TODO(simonb): Extend for 64-bit target libraries.
      6 
      7 #include "leb128.h"
      8 
      9 #include <stdint.h>
     10 #include <vector>
     11 
     12 namespace relocation_packer {
     13 
     14 // Add a single value to the encoding.  Values are encoded with variable
     15 // length.  The least significant 7 bits of each byte hold 7 bits of data,
     16 // and the most significant bit is set on each byte except the last.
     17 void Leb128Encoder::Enqueue(uint32_t value) {
     18   while (value > 127) {
     19     encoding_.push_back((1 << 7) | (value & 127));
     20     value >>= 7;
     21   }
     22   encoding_.push_back(value);
     23 }
     24 
     25 // Add a vector of values to the encoding.
     26 void Leb128Encoder::EnqueueAll(const std::vector<uint32_t>& values) {
     27   for (size_t i = 0; i < values.size(); ++i)
     28     Enqueue(values[i]);
     29 }
     30 
     31 // Decode and retrieve a single value from the encoding.  Read forwards until
     32 // a byte without its most significant bit is found, then read the 7 bit
     33 // fields of the bytes spanned to re-form the value.
     34 uint32_t Leb128Decoder::Dequeue() {
     35   size_t extent = cursor_;
     36   while (encoding_[extent] >> 7)
     37     extent++;
     38 
     39   uint32_t value = 0;
     40   for (size_t i = extent; i > cursor_; --i) {
     41     value = (value << 7) | (encoding_[i] & 127);
     42   }
     43   value = (value << 7) | (encoding_[cursor_] & 127);
     44 
     45   cursor_ = extent + 1;
     46   return value;
     47 }
     48 
     49 // Decode and retrieve all remaining values from the encoding.
     50 void Leb128Decoder::DequeueAll(std::vector<uint32_t>* values) {
     51   while (cursor_ < encoding_.size())
     52     values->push_back(Dequeue());
     53 }
     54 
     55 }  // namespace relocation_packer
     56