Hello,
I wrote a demonstration program for Skybuck's Universal Code Version 4 as
requested.
Especially Rudy Velthuis will from now on address me/call me:
Master Genius Skybuck
=D
Programmed and working in Borland Delphi 2007 also known as CodeGear.
( Should work in Borland Delphi 2006 and Borland Delphi 7 as well, untested
though

)
See comments for any further details
// *** Begin of Code ***
program SkybucksUniversalCodeVersion4UsageExample;
{$APPTYPE CONSOLE}
{
Skybuck's Universal Code Version 4.
Demonstration program
Version 0.01 created on 28 may 2007 by Skybuck Flying.
Now let's pretend we have a variable bit cpu, a variable bit language and
variable bit compiler etc.
Tbits class matches the variable bit concept the most, so we will use that
instead.
The Tbits class allows us to work pretty easily with individual bits.
We could even alter the class to get access to the memory pointer to store
and load it from disks or networks or so.
Or maybe we should simple do that a bit or byte at a time or so... just
mentioned two possibilities.
Wow as I write this a helichopter flies over pretty low making a terrible
freighting noise, like a ufo invasion
For a moment there I thought the aliens were coming to get me LOL.
Ok, back to the topic at hand:
Anyway, Rudy Velthuis was being a smartass on usenet.
He probably did not understand any version of Skybuck's Universal Code and
wanted a demonstration.
He mainly wanted a demonstration how to encode and decode the fields.
He was especially amazed by my claim that even a 1 bit field can be encoded
and decoded successfully and thus seperated from the rest.
This source code demonstrates the principle of Skybuck's Universal Code
Version 4.
The demonstration code consists out of two parts:
1. A encode demonstration.
2. A decode demonstration.
No further processing will be done with the Tbits fields, that's out of the
scope of this demonstration.
Also one more time the concept of Skybuck's Universal Code:
Decoded Data fields: Data
Encoded Data fields : Marker + Length + Data
Explanation:
Marker: a stream of zero's terminated with a one, the number of bits
describes the length of the length stream.
Length: a binary stream of bits, describing the length of the data stream.
Data: a stream of bits.
Note:
The size of the marker stream matches the size of the length stream.
Abstract Encoded Stream example:
Marker1Length1Data1Marker2Length2Data2Marker3Lengt h3Data3
Final note:
Rudy Velthuis called me a genius
From now on he shall address me/call me:
Master Genius Skybuck =D
}
uses
SysUtils, Classes, Math;
// limited to 64 bit values, returns 1 for value zero.
function bits_needed_for_decimal_value( value : extended ) : integer;
begin
// result := round( ceil( log10(1+value) / log10(2) ) );
// same as this I hope:
result := round( ceil( log2(1+value) ) );
if result = 0 then result := 1;
end;
const
BitsPerInt = SizeOf(Integer) * 8;
type
TBitEnum = 0..BitsPerInt - 1;
TBitSet = set of TBitEnum;
// bit value version
procedure OutputBit( var OutputStream : Tbits; var OutputBitIndex : integer;
const BitValue : Byte ); overload;
begin
if BitValue = 0 then
begin
OutputStream[OutputBitIndex] := false;
OutputBitIndex := OutputBitIndex + 1;
end else
if BitValue = 1 then
begin
OutputStream[OutputBitIndex] := true;
OutputBitIndex := OutputBitIndex + 1;
end else
begin
raise Exception.Create('BitValue: ' + IntToStr(BitValue) + ' is not a
valid bit value (you stupid mother****er!!!).');
end;
end;
// boolean value version
// probably more efficient

but more dangerous !
// Is true really 1 ? I have seen some weird **** with boolean values, like
negative values or so.
procedure OutputBit( var OutputStream : Tbits; var OutputBitIndex : integer;
const BitValue : boolean ); overload;
begin
OutputStream[OutputBitIndex] := BitValue;
OutputBitIndex := OutputBitIndex + 1;
end;
function InputBit( const InputStream : Tbits; var InputBitIndex : integer;
var BitValue : boolean ) : boolean;
begin
result := false;
if InputBitIndex < InputStream.Size then
begin
BitValue := InputStream[InputBitIndex];
InputBitIndex := InputBitIndex + 1;
result := true;
end;
end;
procedure EncodeRoutine( VariableBitField : Tbits; OutputStream : Tbits; var
OutputBitIndex : integer );
var
Length : integer;
MarkerStarted : boolean;
BitIndex : integer;
begin
Length := VariableBitField.Size;
MarkerStarted := false;
// output marker field:
// let's use an efficiency trick... we will scan from most significant to
least significant bit
// of the length field... since the most significant bit of the length
will always be set
// this means that will be our starting point... all lower significant
bits have to be outputted as well
// this means we do not need to use logaritm functions to determine the
number of bits required
// this scanning might be faster
// I known I said I don't like high and low, but in this case I make a
****ing exception because
// of the way Delphi/Borland/Code Gear defined the god damn enumeration
lol handy =D :P*
// hopefully I don't regret it later because of stupid problems or
mistakes :P*
for BitIndex := High(TBitEnum) downto Low(TBitEnum) do
begin
if BitIndex in TBitSet(Length) then
begin
MarkerStarted := true;
// least significant bit is the last bit, output a marker bit value of
1 to indicate termination of marker.
if BitIndex = Low(TBitEnum) then
begin
// OutputBit( OutputStream, OutputBitIndex, 1 ); // output a marker
terminator
// let's use the more efficient version
OutputBit( OutputStream, OutputBitIndex, true ); // output a marker
terminator
end else
// all other bits have a marker bit value of 0.
begin
// OutputBit( OutputStream, OutputBitIndex, 0 ); // output a marker
continuator

OutputBit( OutputStream, OutputBitIndex, false ); // output a marker
continuator

end;
end else
begin
// if marker started then binary zero's need a marker bit to be
outputted as well... not just the binary one's

if MarkerStarted then
begin
// if it happens to be the least significant bit then terminate it
as well.
if BitIndex = Low(TBitEnum) then
begin
// OutputBit( OutputStream, OutputBitIndex, 1 ); // output a marker
terminator
OutputBit( OutputStream, OutputBitIndex, true ); // output a
marker terminator
end else
// all other bits have a marker bit value of 0.
begin
// OutputBit( OutputStream, OutputBitIndex, 0 ); // output a marker
continuator

OutputBit( OutputStream, OutputBitIndex, false ); // output a
marker continuator

end;
end;
end;
end;
// output length field:
// same algorithm can be used, this time output the binary bits of the
length field instead of the marker bits
// reset MarkerStarted to false
MarkerStarted := false;
for BitIndex := High(TBitEnum) downto Low(TBitEnum) do
begin
if BitIndex in TBitSet(Length) then
begin
MarkerStarted := true;
// OutputBit( OutputStream, OutputBitIndex, 1 ); // output a binary 1
OutputBit( OutputStream, OutputBitIndex, true ); // output a binary 1
end else
begin
if MarkerStarted then
begin
// OutputBit( OutputStream, OutputBitIndex, 0 ); // output a binary 0
OutputBit( OutputStream, OutputBitIndex, false ); // output a binary
0
end;
// else ignore extra leading/significant binary bits, they all zero.
end;
end;
// output data field:
for BitIndex := 0 to VariableBitField.Size-1 do
begin
OutputBit( OutputStream, OutputBitIndex, VariableBitField[BitIndex] );
end;
end;
procedure DecodeRoutine( var VariableBitField : Tbits; InputStream : Tbits;
var InputBitIndex : integer );
var
Bit : boolean;
LengthValue : integer;
MarkerCount : integer;
LengthCount : integer;
DataCount : integer;
begin
// reset variable bit field just in case

VariableBitField.Size := 0;
// read marker
// using my pseudo code as posted on usenet/the internet/the world wide
web

MarkerCount := 0;
repeat
if InputBit( InputStream, InputBitIndex, Bit ) then
begin
MarkerCount := MarkerCount + 1;
end else
begin
raise Exception.Create('decode error: no more information.');
exit;
end;
until Bit = true;
// read length
// using my pseudo code as posted on usenet/the internet/the world wide
web

LengthValue := 0; // initialize length value to zero.
LengthCount := 0;
repeat
if InputBit( InputStream, InputBitIndex, Bit ) then
begin
if Bit then
begin
// set the binary one in the length binary value, using a delphi
bitset technique
// could have used a special bitset function... but that would
require extra code...
// trying to keep the code short, not necessarily fast

though
performance should not be too bad
// set bit in Length, most significant bit is located at
markercount-1
// not 100% sure if this is correct, but so far it seems to work
just fine

TBitSet(LengthValue) := TBitSet(LengthValue) + [ (MarkerCount-1) -
LengthCount ];
end;// else zero values do not have to be set.
LengthCount := LengthCount + 1;
end else
begin
raise Exception.Create('decode error: no more information.');
exit;
end;
until LengthCount = MarkerCount;
// read data
DataCount := 0;
repeat
if InputBit( InputStream, InputBitIndex, Bit ) then
begin
// set data bit
VariableBitField[DataCount] := Bit;
DataCount := DataCount + 1;
end else
begin
raise Exception.Create('decode error: no more information.');
exit;
end;
until DataCount = LengthValue;
end;
procedure WriteBitStream( BitStream : Tbits );
var
BitIndex : integer;
begin
for BitIndex := 0 to BitStream.Size - 1 do
begin
// nothing is left to chance, the safe way to print it

if BitStream[BitIndex] then
begin
write( 1 );
end else
begin
write( 0 );
end;
end;
end;
var
Field1 : Tbits; // variable bit field 1
Field2 : Tbits; // variable bit field 2
Operation : Tbits; // variable bit operational code
EncodedInformationStream : Tbits; // the encoded information stream.
EncodedInformationStreamBitIndex : integer;
BitIndex : integer;
begin
writeln('program started');
// begin of encode demonstration
Field1 := Tbits.Create;
Field1.Size := 14; // 14 bits.
// set some random bits as the 14 bit value
for BitIndex := 0 to Field1.Size - 1 do
begin
if random(2)=0 then
begin
Field1[BitIndex] := false;
end else
begin
Field1[BitIndex] := true;
end;
end;
Field2 := Tbits.Create;
Field2.Size := 5; // 5 bits
// set some random bits as the 5 bit value
for BitIndex := 0 to Field2.Size - 1 do
begin
if random(2)=0 then
begin
Field2[BitIndex] := false;
end else
begin
Field2[BitIndex] := true;
end;
end;
Operation := Tbits.Create;
Operation.Size := 1; // 1 bit, add operation=0
Operation[0] := false; // only 1 bit to set the first=0, to value 0.
// now Rude Veldhuis ask for a demonstration and a demonstration he will
get.
// The demonstration will have two parts:
// 1. How to encode the information into a "universal stream version 4"
// 2. How to decode the information from a "universal stream version 4"
// The encode demonstration:
EncodedInformationStream := Tbits.Create;
EncodedInformationStream.Size := 0; // the bitset will automatically
resize as necessary, if not mistaken, otherwise increase it everytime a bit
needs to be added.
EncodedInformationStreamBitIndex := 0; // set/reset.
// now the instruction encoding will be:
// operational code, field1, field2
// so first the operationl code is outputted to the information stream.
// for this I shall use a special EncodeRoutine for easy reuse.
EncodeRoutine( Operation, EncodedInformationStream,
EncodedInformationStreamBitIndex );
EncodeRoutine( Field1, EncodedInformationStream,
EncodedInformationStreamBitIndex );
EncodeRoutine( Field2, EncodedInformationStream,
EncodedInformationStreamBitIndex );
// show the encoded information stream bit by bit:
writeln('Operation: ');
writeln('Size: ', Operation.Size );
write('Data Bits: ');
writeBitStream( Operation );
writeln;
writeln;
writeln('Field1: ');
writeln('Size: ', Field1.Size );
write('Data Bits: ');
writeBitStream( Field1 );
writeln;
writeln;
writeln('Field2: ');
writeln('Size: ', Field2.Size );
write('Data Bits: ');
writeBitStream( Field2 );
writeln;
writeln;
writeln('EncodedInformationStream: ');
writeln('Size: ', EncodedInformationStream.Size );
write('Encoded bit stream: ');
writeBitStream( EncodedInformationStream );
writeln;
writeln;
// end of encode demonstration.
writeln('press enter to continue with decode demonstration');
readln;
// begin of decode demonstration.
// the fields have been encoded into the encoded information stream
// now we will cleanup these fields and recreate them as extract/decode
the fields from
// the encoded information stream back into the fields.
Operation.Free;
Field2.Free;
Field1.Free;
Field1 := Tbits.Create;
Field1.Size := 0;
Field2 := Tbits.Create;
Field2.Size := 0;
Operation := Tbits.Create;
Operation.Size := 0;
// reset EncodedInformationStreamBitIndex to zero
EncodedInformationStreamBitIndex := 0;
// now decode the three fields.
DecodeRoutine( Operation, EncodedInformationStream,
EncodedInformationStreamBitIndex );
DecodeRoutine( Field1, EncodedInformationStream,
EncodedInformationStreamBitIndex );
DecodeRoutine( Field2, EncodedInformationStream,
EncodedInformationStreamBitIndex );
// show decoded fields
writeln('Operation: ');
writeln('Size: ', Operation.Size );
write('Data Bits: ');
writeBitStream( Operation );
writeln;
writeln;
writeln('Field1: ');
writeln('Size: ', Field1.Size );
write('Data Bits: ');
writeBitStream( Field1 );
writeln;
writeln;
writeln('Field2: ');
writeln('Size: ', Field2.Size );
write('Data Bits: ');
writeBitStream( Field2 );
writeln;
writeln;
EncodedInformationStream.Free;
writeln('program finished');
writeln('press enter to exit' );
readln;
end.
*** End of Code ***
Bye,
Skybuck.