/*
 * bytestr.cpp
 *
 *  Created on: Apr 20, 2018
 *      Author: armin
 */

#include <bytestr.h>
#include <cassert>

namespace util {

bytestr::bytestr(const string fromHex) { set(fromHex); }

bytestr::bytestr(const byte* fromByte, int len) { set(fromByte, len); }

const byte* bytestr::byteArr() const { return (bytes.data()); }

string bytestr::toHex() const {
  string hexstr;

  for (size_t i = 0; i < size(); i++) {
    char a = (bytes[i] & 0xF0) >> 4;
    char b = bytes[i] & 0x0F;

    if (a < 0xA) {
      hexstr += (a + 0x30);
    } else {
      hexstr += (a - 0xA + 0x41);
    }

    if (b < 0xA) {
      hexstr += (b + 0x30);
    } else {
      hexstr += (b - 0xA + 0x41);
    }
  }

  return (hexstr);
}

void bytestr::set(const string fromHex) {
  string tmpHex = (fromHex.length() % 2) != 0 ? "0" + fromHex : fromHex;
  assert(tmpHex.length() % 2 == 0);

  this->bytes.clear();

  for (size_t i = 0; i < tmpHex.length(); i += 2) {
    int bin = stoi(tmpHex.substr(i, 2), nullptr, 16);
    bytes.push_back(static_cast<byte>(bin));
  }
}

void bytestr::set(const byte* fromBytes, int len) {
  bytes.clear();

  for (int i = 0; i < len; ++i) {
    bytes.push_back(fromBytes[i]);
  }
}

const byte& bytestr::operator[](const int index) const {
  return (bytes[index]);
}

size_t bytestr::size() const { return (bytes.size()); }

ostream& operator<<(ostream& os, const bytestr& bs) {
  os << bs.toHex();
  return (os);
}

} /* namespace util */
