#include "Key.h"

using namespace Framework::Encryption;

// Inhalt der Bytes Klasse aus Schl�ssel.h
// Konstruktor
Bytes::Bytes()
    : ReferenceCounter(),
      bytes(0),
      del(1),
      length(0)
{}

Bytes::Bytes(int len)
    : ReferenceCounter(),
      bytes(new char[len]),
      del(1),
      length(len)
{}

Bytes::Bytes(const char* daten, int len)
    : ReferenceCounter(),
      bytes(new char[len]),
      del(1),
      length(len)
{
    setBytes(daten);
}

// Destruktor
Bytes::~Bytes()
{
    if (del) delete[] bytes;
}

// nicht constant
void Bytes::setBytes(const char* daten)
{
    if (!bytes || !daten) return;
    char* end = bytes + length;
    for (char* c = bytes; c < end; c++, ++daten)
        *c = *daten;
}

void Bytes::setBytes(const char* daten, int len)
{
    if (!daten || !len) return;
    if (del) delete[] bytes;
    del = 1;
    bytes = new char[len];
    this->length = len;
    setBytes(daten);
}

void Bytes::setBytesZ(char* daten, int len)
{
    if (del) delete[] bytes;
    del = 0;
    bytes = daten;
    this->length = len;
}

void Bytes::fill(const char c)
{
    if (!bytes) return;
    char* end = bytes + length;
    for (char* b = bytes; b < end; ++b)
        *b = c;
}

void Bytes::fill(const char c, int len)
{
    if (!bytes) bytes = new char[len];
    len = len > this->length ? this->length : len;
    char* end = bytes + len;
    for (char* b = bytes; b < end; ++b)
        *b = c;
}

void Bytes::fill(const char c, int beg, int end)
{
    if (beg >= length) return;
    if (!bytes) bytes = new char[end - beg];
    end = end > this->length ? this->length : end;
    char* endB = bytes + end;
    for (char* b = bytes + beg; b < endB; ++b)
        *b = c;
}

void Bytes::fill(const char* c, int cLen)
{
    if (!c || !cLen || !bytes) return;
    char* endB = bytes + length;
    const char* endC = c + cLen;
    const char* d = c;
    for (char* b = bytes; b < endB; b++, d = d < endC - 1 ? d + 1 : c)
        *b = *d;
}

void Bytes::set(const char c, int pos)
{
    if (!bytes || pos >= length) return;
    bytes[pos] = c;
}

// constant
int Bytes::getLength() const
{
    return length;
}

char* Bytes::getBytes() const
{
    return bytes;
}

// Inhalt der Schl�ssel Klasse aus Schl�ssel.h
// Konstruktor
Key::Key()
    : ReferenceCounter(),
      key(0),
      length(0),
      pos(0)
{}

Key::Key(const char* s, int len)
    : ReferenceCounter(),
      key(new unsigned char[len]),
      length(len),
      pos(0)
{
    for (int i = 0; i < len; ++i)
        key[i] = s[i];
}

// Destruktor
Key::~Key()
{
    delete[] key;
}

// nicht constant
void Key::setPos(__int64 p)
{
    if (p < 0) p = 0;
    pos = (int)(p % length);
}

void Key::setKey(const char* s, int len)
{
    delete[] key;
    key = new unsigned char[len];
    for (int i = 0; i < len; ++i)
        key[i] = s[i];
    pos = 0;
    this->length = len;
}

void Key::codieren(Bytes* daten)
{
    if (!key || !length)
    {
        daten->release();
        return;
    }
    int dLen = daten->getLength();
    char* bytes = daten->getBytes();
    char* bEnd = bytes + dLen;
    for (char* c = bytes; c < bEnd; ++c)
    {
        *c = (char)(*c + key[pos]);
        ++pos;
        if (pos >= length) pos = 0;
    }
    daten->release();
}

void Key::decodieren(Bytes* daten)
{
    if (!key || !length)
    {
        daten->release();
        return;
    }
    int dLen = daten->getLength();
    char* bytes = daten->getBytes();
    char* bEnd = bytes + dLen;
    for (char* c = bytes; c < bEnd; ++c)
    {
        *c = (char)(*c - key[pos]);
        ++pos;
        if (pos >= length) pos = 0;
    }
    daten->release();
}