ultimatepp/uppdev/BitStream/BitStream.cpp
cxl 3a3cea6319 .uppdev
git-svn-id: svn://ultimatepp.org/upp/trunk@6870 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2014-02-05 08:09:57 +00:00

91 lines
1.9 KiB
C++

#include <Core/Core.h>
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));
}