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 #include "leb128.h"
      6 
      7 #include <stdint.h>
      8 #include <vector>
      9 
     10 #include "elf_traits.h"
     11 
     12 namespace relocation_packer {
     13 
     14 // Empty constructor and destructor to silence chromium-style.
     15 Leb128Encoder::Leb128Encoder() { }
     16 Leb128Encoder::~Leb128Encoder() { }
     17 
     18 // Add a single value to the encoding.  Values are encoded with variable
     19 // length.  The least significant 7 bits of each byte hold 7 bits of data,
     20 // and the most significant bit is set on each byte except the last.
     21 void Leb128Encoder::Enqueue(ELF::Xword value) {
     22   do {
     23     const uint8_t byte = value & 127;
     24     value >>= 7;
     25     encoding_.push_back((value ? 128 : 0) | byte);
     26   } while (value);
     27 }
     28 
     29 // Add a vector of values to the encoding.
     30 void Leb128Encoder::EnqueueAll(const std::vector<ELF::Xword>& values) {
     31   for (size_t i = 0; i < values.size(); ++i)
     32     Enqueue(values[i]);
     33 }
     34 
     35 // Create a new decoder for the given encoded stream.
     36 Leb128Decoder::Leb128Decoder(const std::vector<uint8_t>& encoding) {
     37   encoding_ = encoding;
     38   cursor_ = 0;
     39 }
     40 
     41 // Empty destructor to silence chromium-style.
     42 Leb128Decoder::~Leb128Decoder() { }
     43 
     44 // Decode and retrieve a single value from the encoding.  Read forwards until
     45 // a byte without its most significant bit is found, then read the 7 bit
     46 // fields of the bytes spanned to re-form the value.
     47 ELF::Xword Leb128Decoder::Dequeue() {
     48   ELF::Xword value = 0;
     49 
     50   size_t shift = 0;
     51   uint8_t byte;
     52 
     53   // Loop until we reach a byte with its high order bit clear.
     54   do {
     55     byte = encoding_[cursor_++];
     56     value |= static_cast<ELF::Xword>(byte & 127) << shift;
     57     shift += 7;
     58   } while (byte & 128);
     59 
     60   return value;
     61 }
     62 
     63 // Decode and retrieve all remaining values from the encoding.
     64 void Leb128Decoder::DequeueAll(std::vector<ELF::Xword>* values) {
     65   while (cursor_ < encoding_.size())
     66     values->push_back(Dequeue());
     67 }
     68 
     69 }  // namespace relocation_packer
     70