// Copyright (c) 2012 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_H_
#define SHILL_BYTE_STRING_H_

#include <string>
#include <vector>

#include <base/basictypes.h>

namespace shill {

// Provides a holder of a string of bytes
class ByteString {
 public:
  ByteString() : begin_(data_.begin()) {}
  ByteString(const ByteString &b);
  explicit ByteString(size_t length) : data_(length), begin_(data_.begin()) {}

  ByteString(const unsigned char *data, size_t length)
      : data_(data, data + length), begin_(data_.begin()) {}

  ByteString(const char *data, size_t length)
      : data_(data, data + length), begin_(data_.begin()) {}

  ByteString(const signed char *data, size_t length)
      : data_(data, data + length), begin_(data_.begin()) {}

  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))),
      begin_(data_.begin()) {}

  ByteString &operator=(const ByteString &b);

  unsigned char *GetData();
  const unsigned char *GetConstData() const;
  size_t GetLength() const;

  // Returns a ByteString containing |length| bytes from the ByteString
  // starting at |offset|.  This function truncates the returned string
  // if part (or all) of this requested data lies outside the bounds of
  // this ByteString.
  ByteString GetSubstring(size_t offset, size_t length) const;

  // 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);

  // Creates a ByteString from a string of hexadecimal digits where
  // a pair of hexadecimal digits corresponds to a byte.
  // Returns a default-constructed ByteString if |hex_string| is empty
  // or not a valid string of hexadecimal digits representing a sequence
  // of bytes.
  static ByteString CreateFromHexString(const std::string &hex_string);

  // 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;

  // Converts the string of bytes stored in the ByteString from network order
  // to host order in 32-bit chunks. Returns true on success or false if the
  // length of ByteString is not a multiple of 4.
  bool ConvertFromNetToCPUUInt32Array();

  // Converts the string of bytes stored in the ByteString from host order
  // to network order in 32-bit chunks. Returns true on success or false if the
  // length of ByteString is not a multiple of 4.
  bool ConvertFromCPUToNetUInt32Array();

  bool IsEmpty() const { return GetLength() == 0; }

  // Returns true if every element of |this| is zero, false otherwise.
  bool IsZero() const;

  // Perform an AND operation between each element of |this| with the
  // corresponding byte of |b|.  Returns true if both |this| and |b|
  // are the same length, and as such the operation succeeds; false
  // if they are not.  The result of the operation is stored in |this|.
  bool BitwiseAnd(const ByteString &b);

  // Perform an OR operation between each element of |this| with the
  // corresponding byte of |b|.  Returns true if both |this| and |b|
  // are the same length, and as such the operation succeeds; false
  // if they are not.  The result of the operation is stored in |this|.
  bool BitwiseOr(const ByteString &b);

  // Perform an inversion operation on each of the bits this string.
  void BitwiseInvert();

  bool Equals(const ByteString &b) const;
  void Append(const ByteString &b);
  void Clear();
  void Resize(int size);

  std::string HexEncode() const;

  // Discards |offset| bytes from the beginning of the ByteString (but does
  // not cause a copy).
  void RemovePrefix(size_t offset);

  static bool IsLessThan(const ByteString &lhs, const ByteString &rhs);

 private:
  typedef std::vector<unsigned char> Vector;

  // Converts the string of bytes stored in the ByteString by treating it as
  // an array of unsigned integer of type T and applying |converter| on each
  // unsigned value of type T. Return true on success or false if the length
  // ByteString is not a multiple of sizeof(T).
  template <typename T> bool ConvertByteOrderAsUIntArray(T (*converter)(T));

  Vector data_;

  // Permit chopping-off the front part of the data without requiring a copy.
  Vector::iterator begin_;
  // NO DISALLOW_COPY_AND_ASSIGN -- we assign ByteStrings in STL hashes
};

}  // namespace shill


#endif  // SHILL_BYTE_STRING_H_
