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

#include <base/strings/string_number_conversions.h>

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 std::string& hex_string) {
  std::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);
}

std::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 = std::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
