diff --git a/uppdev/BitStream/BitStream.cpp b/uppdev/BitStream/BitStream.cpp new file mode 100644 index 000000000..b14ea94b5 --- /dev/null +++ b/uppdev/BitStream/BitStream.cpp @@ -0,0 +1,91 @@ +#include + +using namespace Upp; + +class BitsOut { + Stream *stream; + + byte buffer; + int left; + + void Out() { stream->Put(buffer); left = 8; buffer = 0; } + void Flush() { if(left != 8) { Out(); } } + +public: + void Start(Stream& s) { Finish(); stream = &s; left = 8; buffer = 0; } + void Finish() { if(stream) Flush(); stream = NULL; } + + void Put(dword w, int bits); + void Put(bool bit) { Put(bit, 1); } + + BitsOut() { stream = NULL; } + BitsOut(Stream& s) { Start(s); } + ~BitsOut() { Finish(); } +}; + +void BitsOut::Put(dword w, int bits) +{ + ASSERT(bits >= 0 && bits <= 32); + while(bits) { + int q = min(left, bits); + bits -= q; + left -= q; + buffer |= w >> bits << left; + if(left == 0) + Out(); + } +} + +class BitsIn { + Stream *stream; + + byte buffer; + int left; + + void In() { buffer = stream->Get(); left = 8; } + +public: + void Start(Stream& s) { stream = &s; left = 0; } + + dword Get(int bits); + bool Get() { return Get(1); } + + BitsIn() { stream = NULL; } + BitsIn(Stream& s) { Start(s); } +}; + +dword BitsIn::Get(int bits) +{ + dword result = 0; + while(bits) { + if(left == 0) + In(); + int q = min(bits, left); + left -= q; + bits -= q; + result = (result << q) | ((buffer >> left) & (0xff << q >> 8)); + } + return result; +} + +CONSOLE_APP_MAIN +{ + StringStream ss; + BitsOut out; + out.Start(ss); + out.Put(0x123, 12); + out.Put(1234, 12); + out.Put(12345, 15); + out.Put(4, 3); + out.Put(1); + out.Put(0); + out.Put(1); + out.Put(1); + out.Finish(); + ss.Seek(0); + BitsIn in(ss); + DUMP(in.Get(12)); + DUMP(in.Get(12)); + DUMP(in.Get(15)); + DUMP(in.Get(3)); +} diff --git a/uppdev/BitStream/BitStream.upp b/uppdev/BitStream/BitStream.upp new file mode 100644 index 000000000..8a48cce12 --- /dev/null +++ b/uppdev/BitStream/BitStream.upp @@ -0,0 +1,9 @@ +uses + Core; + +file + BitStream.cpp; + +mainconfig + "" = "SSE2"; + diff --git a/uppdev/BitStream/init b/uppdev/BitStream/init new file mode 100644 index 000000000..bab5585a3 --- /dev/null +++ b/uppdev/BitStream/init @@ -0,0 +1,4 @@ +#ifndef _BitStream_icpp_init_stub +#define _BitStream_icpp_init_stub +#include "Core/init" +#endif