text: /*
   *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
   *
   *  Use of this source code is governed by a BSD-style license
   *  that can be found in the LICENSE file in the root of the source
   *  tree. An additional intellectual property rights grant can be found
   *  in the file PATENTS.  All contributing project authors may
   *  be found in the AUTHORS file in the root of the source tree.
   */
  
  #ifndef RTC_BASE_BYTEBUFFER_H_
  #define RTC_BASE_BYTEBUFFER_H_
  
  #include <string>
  
  #include BOSS_WEBRTC_U_rtc_base__buffer_h //original-code:"rtc_base/buffer.h"
  #include BOSS_WEBRTC_U_rtc_base__byteorder_h //original-code:"rtc_base/byteorder.h"
  #include BOSS_WEBRTC_U_rtc_base__constructormagic_h //original-code:"rtc_base/constructormagic.h"
  
  namespace rtc {
  
  class ByteBuffer {
   public:
    enum ByteOrder {
      ORDER_NETWORK = 0,  // Default, use network byte order (big endian).
      ORDER_HOST,         // Use the native order of the host.
    };
  
    explicit ByteBuffer(ByteOrder byte_order) : byte_order_(byte_order) {}
  
    ByteOrder Order() const { return byte_order_; }
  
   private:
    ByteOrder byte_order_;
  
    RTC_DISALLOW_COPY_AND_ASSIGN(ByteBuffer);
  };
  
  template <class BufferClassT>
  class ByteBufferWriterT : public ByteBuffer {
   public:
    // |byte_order| defines order of bytes in the buffer.
    ByteBufferWriterT() : ByteBuffer(ORDER_NETWORK) {
      Construct(nullptr, kDefaultCapacity);
    }
    explicit ByteBufferWriterT(ByteOrder byte_order) : ByteBuffer(byte_order) {
      Construct(nullptr, kDefaultCapacity);
    }
    ByteBufferWriterT(const char* bytes, size_t len) : ByteBuffer(ORDER_NETWORK) {
      Construct(bytes, len);
    }
    ByteBufferWriterT(const char* bytes, size_t len, ByteOrder byte_order)
        : ByteBuffer(byte_order) {
      Construct(bytes, len);
    }
  
    const char* Data() const { return buffer_.data(); }
    size_t Length() const { return buffer_.size(); }
    size_t Capacity() const { return buffer_.capacity(); }
  
    // Write value to the buffer. Resizes the buffer when it is
    // neccessary.
    void WriteUInt8(uint8_t val) {
      WriteBytes(reinterpret_cast<const char*>(&val), 1);
    }
    void WriteUInt16(uint16_t val) {
      uint16_t v = (Order() == ORDER_NETWORK) ? HostToNetwork16(val) : val;
      WriteBytes(reinterpret_cast<const char*>(&v), 2);
    }
    void WriteUInt24(uint32_t val) {
      uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
      char* start = reinterpret_cast<char*>(&v);
      if (Order() == ORDER_NETWORK || IsHostBigEndian()) {
        ++start;
      }
      WriteBytes(start, 3);
    }
    void WriteUInt32(uint32_t val) {
      uint32_t v = (Order() == ORDER_NETWORK) ? HostToNetwork32(val) : val;
      WriteBytes(reinterpret_cast<const char*>(&v), 4);
    }
    void WriteUInt64(uint64_t val) {
      uint64_t v = (Order() == ORDER_NETWORK) ? HostToNetwork64(val) : val;
      WriteBytes(reinterpret_cast<const char*>(&v), 8);
    }
    // Serializes an unsigned varint in the format described by
    // https://developers.google.com/protocol-buffers/docs/encoding#varints
    // with the caveat that integers are 64-bit, not 128-bit.
    void WriteUVarint(uint64_t val) {
      while (val >= 0x80) {
        // Write 7 bits at a time, then set the msb to a continuation byte
        // (msb=1).
        char byte = static_cast<char>(val) | 0x80;
        WriteBytes(&byte, 1);
        val >>= 7;
      }
      char last_byte = static_cast<char>(val);
      WriteBytes(&last_byte, 1);
    }
    void WriteString(const std::string& val) {
      WriteBytes(val.c_str(), val.size());
    }
    void WriteBytes(const char* val, size_t len) { buffer_.AppendData(val, len); }
  
    // Reserves the given number of bytes and returns a char* that can be written
    // into. Useful for functions that require a char* buffer and not a
    // ByteBufferWriter.
    char* ReserveWriteBuffer(size_t len) {
      buffer_.SetSize(buffer_.size() + len);
      return buffer_.data();
    }
  
    // Resize the buffer to the specified |size|.
    void Resize(size_t size) { buffer_.SetSize(size); }
  
    // Clears the contents of the buffer. After this, Length() will be 0.
    void Clear() { buffer_.Clear(); }
  
   private:
    static constexpr size_t kDefaultCapacity = 4096;
  
    void Construct(const char* bytes, size_t size) {
      if (bytes) {
        buffer_.AppendData(bytes, size);
      } else {
        buffer_.EnsureCapacity(size);
      }
    }
  
    BufferClassT buffer_;
  
    // There are sensible ways to define these, but they aren't needed in our code
    // base.
    RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferWriterT);
  };
  
  class ByteBufferWriter : public ByteBufferWriterT<BufferT<char>> {
   public:
    // |byte_order| defines order of bytes in the buffer.
    ByteBufferWriter();
    explicit ByteBufferWriter(ByteOrder byte_order);
    ByteBufferWriter(const char* bytes, size_t len);
    ByteBufferWriter(const char* bytes, size_t len, ByteOrder byte_order);
  
   private:
    RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferWriter);
  };
  
  // The ByteBufferReader references the passed data, i.e. the pointer must be
  // valid during the lifetime of the reader.
  class ByteBufferReader : public ByteBuffer {
   public:
    ByteBufferReader(const char* bytes, size_t len);
    ByteBufferReader(const char* bytes, size_t len, ByteOrder byte_order);
  
    // Initializes buffer from a zero-terminated string.
    explicit ByteBufferReader(const char* bytes);
  
    explicit ByteBufferReader(const Buffer& buf);
  
    explicit ByteBufferReader(const ByteBufferWriter& buf);
  
    // Returns start of unprocessed data.
    const char* Data() const { return bytes_ + start_; }
    // Returns number of unprocessed bytes.
    size_t Length() const { return end_ - start_; }
  
    // Read a next value from the buffer. Return false if there isn't
    // enough data left for the specified type.
    bool ReadUInt8(uint8_t* val);
    bool ReadUInt16(uint16_t* val);
    bool ReadUInt24(uint32_t* val);
    bool ReadUInt32(uint32_t* val);
    bool ReadUInt64(uint64_t* val);
    bool ReadUVarint(uint64_t* val);
    bool ReadBytes(char* val, size_t len);
  
    // Appends next |len| bytes from the buffer to |val|. Returns false
    // if there is less than |len| bytes left.
    bool ReadString(std::string* val, size_t len);
  
    // Moves current position |size| bytes forward. Returns false if
    // there is less than |size| bytes left in the buffer. Consume doesn't
    // permanently remove data, so remembered read positions are still valid
    // after this call.
    bool Consume(size_t size);
  
   private:
    void Construct(const char* bytes, size_t size);
  
    const char* bytes_;
    size_t size_;
    size_t start_;
    size_t end_;
  
    RTC_DISALLOW_COPY_AND_ASSIGN(ByteBufferReader);
  };
  
  }  // namespace rtc
  
  #endif  // RTC_BASE_BYTEBUFFER_H_
  