// Copyright 2018 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.

#include "shill/net/byte_string.h"

#include <netinet/in.h>
#include <string.h>

#include <algorithm>

#include <base/strings/string_number_conversions.h>

using std::min;
using std::string;
using std::vector;

namespace shill {

unsigned char* ByteString::GetData() {
  return (GetLength() == 0) ? nullptr : &data_.front();
}

const unsigned char* ByteString::GetConstData() const {
  return (GetLength() == 0) ? nullptr : &data_.front();
}

const char* ByteString::GetConstCString() const {
  return reinterpret_cast<const char*>(GetConstData());
}

size_t ByteString::GetLength() const {
  return data_.size();
}

ByteString ByteString::GetSubstring(size_t offset, size_t length) const {
  if (offset > GetLength()) {
    offset = GetLength();
  }
  if (length > GetLength() - offset) {
    length = GetLength() - offset;
  }
  return ByteString(GetConstData() + offset, length);
}

// static
ByteString ByteString::CreateFromCPUUInt32(uint32_t val) {
  return ByteString(reinterpret_cast<unsigned char*>(&val), sizeof(val));
}

// static
ByteString ByteString::CreateFromNetUInt32(uint32_t val) {
  return CreateFromCPUUInt32(ntohl(val));
}

// static
ByteString ByteString::CreateFromHexString(const string& hex_string) {
  vector<uint8_t> bytes;
  if (!base::HexStringToBytes(hex_string, &bytes)) {
    return ByteString();
  }
  return ByteString(&bytes.front(), bytes.size());
}

bool ByteString::ConvertToCPUUInt32(uint32_t* val) const {
  if (val == nullptr || GetLength() != sizeof(*val)) {
    return false;
  }
  memcpy(val, GetConstData(), sizeof(*val));

  return true;
}

bool ByteString::ConvertToNetUInt32(uint32_t* val) const {
  if (!ConvertToCPUUInt32(val)) {
    return false;
  }
  *val = ntohl(*val);
  return true;
}

template <typename T>
bool ByteString::ConvertByteOrderAsUIntArray(T (*converter)(T)) {
  size_t length = GetLength();
  if ((length % sizeof(T)) != 0) {
    return false;
  }
  for (auto i = data_.begin(); i != data_.end(); i += sizeof(T)) {
    // Take care of word alignment.
    T val;
    memcpy(&val, &(*i), sizeof(T));
    val = converter(val);
    memcpy(&(*i), &val, sizeof(T));
  }
  return true;
}

bool ByteString::ConvertFromNetToCPUUInt32Array() {
  return ConvertByteOrderAsUIntArray(ntohl);
}

bool ByteString::ConvertFromCPUToNetUInt32Array() {
  return ConvertByteOrderAsUIntArray(htonl);
}

bool ByteString::IsZero() const {
  for (const auto& i : data_) {
    if (i != 0) {
      return false;
    }
  }
  return true;
}

bool ByteString::BitwiseAnd(const ByteString& b) {
  if (GetLength() != b.GetLength()) {
    return false;
  }
  auto lhs = data_.begin();
  for (const auto& rhs : b.data_) {
    *lhs++ &= rhs;
  }
  return true;
}

bool ByteString::BitwiseOr(const ByteString& b) {
  if (GetLength() != b.GetLength()) {
    return false;
  }
  auto lhs = data_.begin();
  for (const auto& rhs : b.data_) {
    *lhs++ |= rhs;
  }
  return true;
}

void ByteString::BitwiseInvert() {
  for (auto& i : data_) {
    i = ~i;
  }
}

bool ByteString::Equals(const ByteString& b) const {
  if (GetLength() != b.GetLength()) {
    return false;
  }
  auto lhs = data_.begin();
  for (const auto& rhs : b.data_) {
    if (*lhs++ != rhs) {
      return false;
    }
  }
  return true;
}

void ByteString::Append(const ByteString& b) {
  data_.insert(data_.end(), b.data_.begin(), b.data_.end());
}

void ByteString::Clear() {
  data_.clear();
}

void ByteString::Resize(int size) {
  data_.resize(size, 0);
}

string ByteString::HexEncode() const {
  return base::HexEncode(GetConstData(), GetLength());
}

bool ByteString::CopyData(size_t size, void* output) const {
  if (output == nullptr || GetLength() < size) {
    return false;
  }
  memcpy(output, GetConstData(), size);
  return true;
}

// static
bool ByteString::IsLessThan(const ByteString& lhs, const ByteString& rhs) {
  size_t byte_count = min(lhs.GetLength(), rhs.GetLength());
  int result = memcmp(lhs.GetConstData(), rhs.GetConstData(), byte_count);
  if (result == 0) {
    return lhs.GetLength() < rhs.GetLength();
  }
  return result < 0;
}

}  // namespace shill
