/*!
  \file
  \brief パケット処理の補助

  \author Satofumi KAMIMURA

  $Id: PacketUtils.cpp 1474 2009-11-01 05:33:08Z satofumi $
*/

#include "PacketUtils.h"
#include <cstring>
#include <cstdio>

using namespace qrk;
using namespace std;


void qrk::createPacketHeader(Packet& packet, const char* type)
{
  packet.resize(5, 0);
  packet[3] = type[0];
  packet[4] = type[1];
}


void qrk::setPacketLength(Packet& packet)
{
  size_t length = packet.size();
  packet[0] = (length >> 16) & 0xff;
  packet[1] = (length >> 8) & 0xff;
  packet[2] = length & 0xff;
}


size_t qrk::packetLength(const Packet& packet)
{
  unsigned long length = 0;
  for (size_t i = 0; i < PacketControl::Length; ++i) {
    length <<= 8;
    length += static_cast<unsigned char>(packet[i]);
  }
  return length;
}


string qrk::packetType(const Packet& packet)
{
  char buffer[PacketControl::Type + 1];
  buffer[0] = packet[PacketControl::Length + 0];
  buffer[1] = packet[PacketControl::Length + 1];
  buffer[PacketControl::Type] = '\0';

  return string(buffer);
}


void qrk::addParameter(Packet& packet, const char* text)
{
  // !!! resize() 後にコピーで配置するようにする
  size_t n = strlen(text);
  for (size_t i = 0; i < n; ++i) {
    packet.push_back(text[i]);
  }
}


void qrk::addParameter(Packet& packet, size_t value, size_t byte)
{
  for (int i = 3; i >= 0; --i) {
    char ch = static_cast<unsigned char>((value & 0xff000000) >> 24);
    value <<= 8;

    if (static_cast<int>(byte) > i) {
      packet.push_back(ch);
    }
  }
}


void qrk::addParameter(Packet& packet, ClientId value)
{
  // !!! addParameter(, size_t) と共通にできるように実装し直す
  for (size_t i = 0; i < 2; ++i) {
    char ch = static_cast<unsigned char>((value & 0xff00) >> 8);
    value <<= 8;

    packet.push_back(ch);
  }
}


size_t qrk::parameter(const char* packet_data, size_t byte)
{
  size_t value = 0;
  for (size_t i = 0; i < byte; ++i) {
    value <<= 8;
    value += static_cast<unsigned char>(packet_data[i]);
  }
  return value;
}


void qrk::dumpPacket(const Packet& packet)
{
  size_t n = packet.size();
  for (size_t i = 0; i < n; ++i) {
    char ch = packet[i];
    if (isprint(ch)) {
      fprintf(stderr, "%c", ch);
    } else {
      fprintf(stderr, "[%02x]", (unsigned char)ch);
    }
  }
}
