// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SHILL_BYTE_STRING_
#define SHILL_BYTE_STRING_

#include <string>
#include <vector>

#include <base/basictypes.h>

namespace shill {

// Provides a holder of a string of bytes
class ByteString {
 public:
  ByteString() {}
  ByteString(const ByteString &b) : data_(b.data_) {}
  explicit ByteString(size_t length) : data_(length) {}
  ByteString(const unsigned char *data, size_t length)
      : data_(data, data + length) {}
  ByteString(const std::string &data, bool copy_terminator)
    : data_(reinterpret_cast<const unsigned char *>(data.c_str()),
            reinterpret_cast<const unsigned char *>(data.c_str() +
                                                    data.length() +
                                                    (copy_terminator ?
                                                     1 : 0))) {}

  ByteString &operator=(const ByteString &b) {
    data_ = b.data_;
    return *this;
  }

  // Inserts a uint32 into a ByteString in cpu-order
  static ByteString CreateFromCPUUInt32(uint32 val);
  // Inserts a uint32 into a ByteString in network-order
  static ByteString CreateFromNetUInt32(uint32 val);

  unsigned char *GetData() { return data_.data(); }
  const unsigned char *GetConstData() const { return data_.data(); }
  size_t GetLength() const { return data_.size(); }

  // Converts to a uint32 from a host-order value stored in the ByteString
  // Returns true on success
  bool ConvertToCPUUInt32(uint32 *val) const;
  // Converts to a uint32 from a network-order value stored in the ByteString
  // Returns true on success
  bool ConvertToNetUInt32(uint32 *val) const;

  bool IsEmpty() const { return GetLength() == 0; }
  bool IsZero() const;
  bool Equals(const ByteString &b) const;
  void Append(const ByteString &b);
  void Resize(int size) {
    data_.resize(size, 0);
  }

  std::string HexEncode() const;

 private:
  std::vector<unsigned char> data_;
  // NO DISALLOW_COPY_AND_ASSIGN -- we assign ByteStrings in STL hashes
};

}  // namespace shill


#endif  // SHILL_BYTE_STRING_
