ich hab hier schon mal vor 1 2 Jahren über genau die selbe Klasse geschrieben die ich euch jetzt zeigen werde. Mein Problem ist dass diese BitStream-Klasse eigentlich zu den includes einer Biblothek gehören soll die ich schreibe. Ich schaffe es aber in GCC (4.4.1 hat Ubuntu soweit ich weiss) nicht dass als reines Header-File zu schreiben, da ich manche Methoden für bestimmte Dateitypen definiere und GCC das im C++-File haben will.
Das ist der Header
Code: Alles auswählen
#ifndef _INCLUDE_yogi_BITSTREAM_
#define _INCLUDE_yogi_BITSTREAM_
/*!
    Copright: Kai "DrHalan" Mast - http://www.freakybytes.org
    This file is part of yNetwork. See yNetwork.h for license information.
*/
#include <yNetwork/yNetwork.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
namespace yogi
{
class BitStream
{
    public:
        BitStream()
        {
            bitIndex = 0;
        }
        BitStream(const u32 packetSize)
        {
            bitIndex = 0;
            buffer.resize(packetSize, 0);
        }
        BitStream(const c8* pCharBuffer, const u32 length)
        {
            bitIndex = 0;
            //Load in the buffer to be used
            buffer.resize(length);
            memcpy(&buffer[0], pCharBuffer, length);
        }
        //! WRITE FUNCTIONS
        template<class T> void write(const T value, const bool resize = true)
        {
            if(resize)
                buffer.resize((bitIndex+(sizeof(T)*8)+7)/8);
            for(u8 copyBits = 0; copyBits < (u8) (sizeof(T)*8); ++copyBits)
            {
                buffer[(bitIndex+copyBits)/8] |= ((value >> ((sizeof(T)*8-1)-copyBits)) & 0x1)<<(7-(bitIndex+copyBits)%8);
            }
            bitIndex += sizeof(T)*8;
        }
        template<class T> void writeArray(const std::vector<T> & value, const bool resize = true)
        {
            u16 size = u16(value.size());
            this->write<u16>(size, resize);
            if(resize)
                buffer.resize((bitIndex+(sizeof(T)*8*size)+7)/8);
            for(u32 u = 0; u < size; u++)
            {
                this->write(value[u], false);
            }
        }
        //! Nearly the same as writeArray but you've to give the size manually
        //! Also it takes a pointe to an T-Array
        //! Mainly used by the UDP-Class itself
        template<class T> void writeRawArray(const T* value, const u32 size, const bool resize = true)
        {
            if(resize)
                buffer.resize((bitIndex+(size*8)+7)/8);
            for(u32 u = 0; u < size; u++)
            {
                this->write<T>(value[u], false);
            }
        }
        //! READ FUNCTIONS
        template<class T> T read(const bool increment = true)
        {
            T value = 0;
            for(c8 copyBits = 0; copyBits < (c8) (sizeof(T)*8); ++copyBits)
            {
                value <<= 1;
                value |= (buffer[(bitIndex+copyBits)/8]>>(7-(bitIndex+copyBits)%8)) & 0x1;
            }
            if(increment)
                bitIndex += sizeof(T)*8;
            return value;
        }
        template<class T> std::vector<T> readArray(const bool increment = true)
        {
            u16 size = read<u16>(true);
            std::vector<T> value;
            value.resize(size);
            for(u16 cycleArray = 0; cycleArray < size; ++cycleArray)
            {
                this->read<T>(true);
            }
            if(!increment)
                bitIndex -= sizeof(T)*8*size+8;
            return value;
        }
        //! Nearly the same as ready array but you've to give the size manually
        //! Also it returns a pointer to a T-Array
        //! Mainly used by the UDP-Class itself
        template<class T> T* readRawArray(const u32 size, const bool increment = true)
        {
            T* value = new T[size];
            for(u32 u = 0; u < size; u++)
            {
                value[u] = this->read<T>(true);
            }
            if(!increment)
                bitIndex -= size*8;
            return value;
        }
        //! Copy a Raw Array directly to another BitStream (e.g. used in TCP port)
        template<class T> void copyRawArray(BitStream* other, const u32 size, const bool increment = true, const bool resize = true)
        {
            for(u32 u = 0; u < size; u++)
            {
                other->write<c8>(this->read<T>(true), resize);
            }
            if(!increment)
                bitIndex -= size*8;
        }
        //! RESET AND SET BITINDEX
        void resetBitIndex()
        {
            bitIndex = 0;
        }
        void setBitIndex(const s32 index)
        {
            bitIndex = index;
        }
        void setByteIndex(const u32 index)
        {
            bitIndex = 8*index;
        }
        u64 getBitIndex() const
        {
            return bitIndex;
        }
        u32 getByteIndex() const
        {
            return bitIndex/8;
        }
        u32 getLength() const
        {
            return u32(buffer.size());
        }
        c8* getData(const bool copy = false)
        {
            if(copy)
            {
                c8* dataCopy = new c8[this->getLength()];
                memcpy(dataCopy, &buffer[0], this->getLength());
                return dataCopy;
            }
            else
                return &buffer[0];
        }
        std::string getDataAsString()
        {
            return std::string(this->getData(), this->getLength());
        }
        std::vector<c8> getDataAsVector() const
        {
            return buffer;
        }
        void resetBuffer()
        {
            for(std::vector<c8>::iterator bufferItr = buffer.begin(); bufferItr != buffer.end(); ++bufferItr)
            {
                (*bufferItr) = 0;
            }
        }
        //! Some operators for easier acess
        c8 operator[](const u32 pos) const
        {
            if(pos > buffer.size())
                return 0;
            return buffer[pos];
        }
        bool operator==(const BitStream& other) const
        {
            if(other.getLength() != this->getLength())
                return false;
            std::vector<c8> otherData = other.getDataAsVector();
            for(u32 u = 0; u < this->getLength(); u++)
            {
                if(buffer[u] != otherData[u])
                    return false;
            }
            return true;
        }
        void operator+= (BitStream& other)
        {
            u64 oldindex = other.getBitIndex();
            other.setBitIndex(0);
            for(u32 u = 0; u < other.getLength(); u++)
            {
                this->write<c8>(other[u]);
            }
            bitIndex += other.getLength();
            other.setBitIndex(oldindex);
        }
        void operator= (const std::string str)
        {
            buffer.resize(str.length());
            for(u32 u = 0; u < str.length(); u++)
            {
                buffer[u] = str[u];
            }
        }
    private:
        //! The char-array holding the data
        std::vector<c8> buffer;
        //! The reading / writing position
        u64 bitIndex;
};
//! Specialisations
template<> void BitStream::writeArray<f32>(const std::vector<f32> &value, const bool resize);
template<> void BitStream::write<bool>(const bool value, const bool resize);
template<> void BitStream::write<std::string>(std::string value, const bool resize);
template<> void BitStream::write<f32>(const f32 value, const bool resize);
template<> bool BitStream::read<bool>(const bool increment);
template<> f32 BitStream::read<f32>(const bool increment);
template<> std::vector<f32> BitStream::readArray<f32>(const bool increment);
template<> std::string BitStream::read<std::string>(const bool increment);
}
#endif
Code: Alles auswählen
#include "BitStream.h"
namespace yogi
{
//! Some specialized implementations
//! Makes it easy to improve the BitStreams perfomance without modifining the methods-names
//! (by adding new templates etc)
template<> void BitStream::writeArray<f32>(const std::vector<f32> &value, const bool resize)
{
    s32 temp;
    c8 size = c8(value.size());
    this->write<c8>(size, resize);
    if(resize)
        buffer.resize((bitIndex+(sizeof(float)*8*size)+7)/8);
    for(c8 cycleArray = 0; cycleArray < size; ++cycleArray)
    {
        memcpy(&temp,&value[cycleArray],sizeof(f32));
        write<s32>(temp, resize);
    }
}
template<> void BitStream::write<bool>(const bool value, const bool resize)
{
    if(resize)
        buffer.resize((bitIndex+8)/8);
    buffer[(bitIndex)/8] |= (value)<<(7-(bitIndex)%8);
    bitIndex++;
}
template<> void BitStream::write<std::string>(std::string value, const bool resize)
{
    write<c8>(c8(value.size()), resize);
    if(resize)
        buffer.resize((bitIndex+((value.size())*8)+7)/8);
    for(std::string::iterator it = value.begin(); it != value.end(); it++)
    {
        this->write<c8>(*it, false);
    }
}
template<> void BitStream::write<f32>(const f32 value, const bool resize)
{
    s32 Temp;
    memcpy(&Temp,&value,sizeof(f32));
    this->write<s32>(Temp, resize);
}
template<> bool BitStream::read<bool>(const bool increment)
{
    bool value = (buffer[bitIndex/8] >> (7-bitIndex%8)) & 0x1;
    if(increment)
        bitIndex++;
    return value;
}
template<> f32 BitStream::read<f32>(const bool increment)
{
    s32 temp = read<s32>(increment);
    f32 value;
    memcpy(&value, &temp, sizeof(f32));
    return value;
}
template<> std::vector<f32> BitStream::readArray<f32>(const bool increment)
{
    s32 temp;
    c8 size = read<c8>(true);
    std::vector<f32> value;
    value.resize(size);
    for(c8 cycleArray = 0; cycleArray < size; cycleArray++)
    {
        temp = read<s32>(true);
        memcpy(&value[cycleArray], &temp, sizeof(f32));
    }
    if(!increment)
        bitIndex -= sizeof(f32)*8*size+8;
    return value;
}
template<> std::string BitStream::read<std::string>(const bool increment)
{
    std::string value;
    s32 length = read<c8>(true);
    value.resize(length);
    for(std::string::iterator stringItr = value.begin(); stringItr != value.end(); stringItr++)
    {
        this->read<c8>(true);
    }
    if(!increment)
        bitIndex -= length*8 + 8;
    return value;
}
} //! end namespace yogi
grüße,
Halan