Bitwise IO: Difference between revisions

Content added Content deleted
m (Imlementation in Red programming language)
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 559: Line 559:


return 0;
return 0;
}</lang>

=={{header|C sharp|C#}}==
<lang csharp>using System;
using System.IO;

public class BitReader
{
uint readData = 0;
int startPosition = 0;
int endPosition = 0;

public int InBuffer
{
get { return endPosition - startPosition; }
}

private Stream stream;

public Stream BaseStream
{
get { return stream; }
}

public BitReader(Stream stream)
{
this.stream = stream;
}

void EnsureData(int bitCount)
{
int readBits = bitCount - InBuffer;
while (readBits > 0)
{
int b = BaseStream.ReadByte();

if (b < 0) throw new InvalidOperationException("Unexpected end of stream");

readData |= checked((uint)b << endPosition);
endPosition += 8;
readBits -= 8;
}
}

public bool ReadBit()
{
return Read(1) > 0;
}

public int Read(int bitCount)
{
EnsureData(bitCount);

int result = (int)(readData >> startPosition) & ((1 << bitCount) - 1);
startPosition += bitCount;
if (endPosition == startPosition)
{
endPosition = startPosition = 0;
readData = 0;
}
else if (startPosition >= 8)
{
readData >>= startPosition;
endPosition -= startPosition;
startPosition = 0;
}

return result;
}

public void Align()
{
endPosition = startPosition = 0;
readData = 0;
}
}

public class BitWriter
{
uint data = 0;
int dataLength = 0;
Stream stream;

public Stream BaseStream
{
get { return stream; }
}

public int BitsToAligment
{
get { return (32 - dataLength) % 8; }
}

public BitWriter(Stream stream)
{
this.stream = stream;
}

public void WriteBit(bool value)
{
Write(value ? 1 : 0, 1);
}

public void Write(int value, int length)
{
uint currentData = data | checked((uint)value << dataLength);
int currentLength = dataLength + length;
while (currentLength >= 8)
{
BaseStream.WriteByte((byte)currentData);
currentData >>= 8;
currentLength -= 8;
}
data = currentData;
dataLength = currentLength;
}

public void Align()
{
if (dataLength > 0)
{
BaseStream.WriteByte((byte)data);

data = 0;
dataLength = 0;
}
}
}

class Program
{
static void Main(string[] args)
{
MemoryStream ms = new MemoryStream();
BitWriter writer = new BitWriter(ms);
writer.WriteBit(true);
writer.Write(5, 3);
writer.Write(0x0155, 11);
writer.Align();

ms.Position = 0;
BitReader reader = new BitReader(ms);
Console.WriteLine(reader.ReadBit());
Console.WriteLine(reader.Read(3));
Console.WriteLine(reader.Read(11).ToString("x4"));
reader.Align();
}
}</lang>
}</lang>


Line 737: Line 884:
⇒ ABORT
⇒ ABORT
</lang>
</lang>

=={{header|C sharp|C#}}==
<lang csharp>using System;
using System.IO;

public class BitReader
{
uint readData = 0;
int startPosition = 0;
int endPosition = 0;

public int InBuffer
{
get { return endPosition - startPosition; }
}

private Stream stream;

public Stream BaseStream
{
get { return stream; }
}

public BitReader(Stream stream)
{
this.stream = stream;
}

void EnsureData(int bitCount)
{
int readBits = bitCount - InBuffer;
while (readBits > 0)
{
int b = BaseStream.ReadByte();

if (b < 0) throw new InvalidOperationException("Unexpected end of stream");

readData |= checked((uint)b << endPosition);
endPosition += 8;
readBits -= 8;
}
}

public bool ReadBit()
{
return Read(1) > 0;
}

public int Read(int bitCount)
{
EnsureData(bitCount);

int result = (int)(readData >> startPosition) & ((1 << bitCount) - 1);
startPosition += bitCount;
if (endPosition == startPosition)
{
endPosition = startPosition = 0;
readData = 0;
}
else if (startPosition >= 8)
{
readData >>= startPosition;
endPosition -= startPosition;
startPosition = 0;
}

return result;
}

public void Align()
{
endPosition = startPosition = 0;
readData = 0;
}
}

public class BitWriter
{
uint data = 0;
int dataLength = 0;
Stream stream;

public Stream BaseStream
{
get { return stream; }
}

public int BitsToAligment
{
get { return (32 - dataLength) % 8; }
}

public BitWriter(Stream stream)
{
this.stream = stream;
}

public void WriteBit(bool value)
{
Write(value ? 1 : 0, 1);
}

public void Write(int value, int length)
{
uint currentData = data | checked((uint)value << dataLength);
int currentLength = dataLength + length;
while (currentLength >= 8)
{
BaseStream.WriteByte((byte)currentData);
currentData >>= 8;
currentLength -= 8;
}
data = currentData;
dataLength = currentLength;
}

public void Align()
{
if (dataLength > 0)
{
BaseStream.WriteByte((byte)data);

data = 0;
dataLength = 0;
}
}
}

class Program
{
static void Main(string[] args)
{
MemoryStream ms = new MemoryStream();
BitWriter writer = new BitWriter(ms);
writer.WriteBit(true);
writer.Write(5, 3);
writer.Write(0x0155, 11);
writer.Align();

ms.Position = 0;
BitReader reader = new BitReader(ms);
Console.WriteLine(reader.ReadBit());
Console.WriteLine(reader.Read(3));
Console.WriteLine(reader.Read(11).ToString("x4"));
reader.Align();
}
}</lang>


=={{header|D}}==
=={{header|D}}==
Line 1,451: Line 1,451:
69</lang>
69</lang>
Note: this implementation writes the bytes to the session (which is to say, it just gets displayed like any other result. Also, the compressed result is represented as bits - like 1 0 1 0 1... You'll of course need other code when you want to do other things.)
Note: this implementation writes the bytes to the session (which is to say, it just gets displayed like any other result. Also, the compressed result is represented as bits - like 1 0 1 0 1... You'll of course need other code when you want to do other things.)



=={{header|Julia}}==
=={{header|Julia}}==
Line 1,901: Line 1,900:
print pack("C1", $v);
print pack("C1", $v);
}</lang>
}</lang>

=={{header|Perl 6}}==
<lang perl6>sub encode-ascii(Str $s) {
my @b = flat $s.ords».fmt("%07b")».comb;
@b.push(0) until @b %% 8; # padding
Buf.new: gather while @b { take reduce * *2+*, (@b.pop for ^8) }
}

sub decode-ascii(Buf $b) {
my @b = flat $b.list».fmt("%08b")».comb;
@b.shift until @b %% 7; # remove padding
@b = gather while @b { take reduce * *2+*, (@b.pop for ^7) }
return [~] @b».chr;
}
say my $encode = encode-ascii 'STRING';
say decode-ascii $encode;</lang>
{{out}}
<pre>Buf:0x<03 8b 99 29 4a e5>
STRING</pre>


=={{header|Phix}}==
=={{header|Phix}}==
Line 2,037: Line 2,017:
simply ignore retrieved zero bytes, but that could fairly obviously create problems for some forms of binary data. A better solution
simply ignore retrieved zero bytes, but that could fairly obviously create problems for some forms of binary data. A better solution
might be for the data to embed or prefix it's own length. The other four (commented-out) test values do not exhibit this problem.
might be for the data to embed or prefix it's own length. The other four (commented-out) test values do not exhibit this problem.

=={{header|PicoLisp}}==
<lang PicoLisp>(de write7bitwise (Lst)
(let (Bits 0 Byte)
(for N Lst
(if (=0 Bits)
(setq Bits 7 Byte (* 2 N))
(wr (| Byte (>> (dec 'Bits) N)))
(setq Byte (>> (- Bits 8) N)) ) )
(unless (=0 Bits)
(wr Byte) ) ) )

(de read7bitwise ()
(make
(let (Bits 0 Byte)
(while (rd 1)
(let N @
(link
(if (=0 Bits)
(>> (one Bits) N)
(| Byte (>> (inc 'Bits) N)) ) )
(setq Byte (& 127 (>> (- Bits 7) N))) ) )
(when (= 7 Bits)
(link Byte) ) ) ) )</lang>
<lang PicoLisp>(out 'a (write7bitwise (127 0 127 0 127 0 127 0 127)))
(hd 'a)
(in 'a (println (read7bitwise)))

(out 'a (write7bitwise (0 127 0 127 0 127 0 127 0)))
(hd 'a)
(in 'a (println (read7bitwise)))

(out 'a (write7bitwise (mapcar char (chop "STRING"))))
(hd 'a)
(println (mapcar char (in 'a (read7bitwise))))</lang>
{{out}}
<pre>00000000 FE 03 F8 0F E0 3F 80 FE .....?..
(127 0 127 0 127 0 127 0)
00000000 01 FC 07 F0 1F C0 7F 00 .......
(0 127 0 127 0 127 0 127)
00000000 A7 52 94 99 D1 C0 .R....
("S" "T" "R" "I" "N" "G")</pre>


=={{header|PL/I}}==
=={{header|PL/I}}==
Line 2,081: Line 2,103:
1010011101010010100101001001100111010001111010011000110100010100000000
1010011101010010100101001001100111010001111010011000110100010100000000
</pre>
</pre>

=={{header|PicoLisp}}==
<lang PicoLisp>(de write7bitwise (Lst)
(let (Bits 0 Byte)
(for N Lst
(if (=0 Bits)
(setq Bits 7 Byte (* 2 N))
(wr (| Byte (>> (dec 'Bits) N)))
(setq Byte (>> (- Bits 8) N)) ) )
(unless (=0 Bits)
(wr Byte) ) ) )

(de read7bitwise ()
(make
(let (Bits 0 Byte)
(while (rd 1)
(let N @
(link
(if (=0 Bits)
(>> (one Bits) N)
(| Byte (>> (inc 'Bits) N)) ) )
(setq Byte (& 127 (>> (- Bits 7) N))) ) )
(when (= 7 Bits)
(link Byte) ) ) ) )</lang>
<lang PicoLisp>(out 'a (write7bitwise (127 0 127 0 127 0 127 0 127)))
(hd 'a)
(in 'a (println (read7bitwise)))

(out 'a (write7bitwise (0 127 0 127 0 127 0 127 0)))
(hd 'a)
(in 'a (println (read7bitwise)))

(out 'a (write7bitwise (mapcar char (chop "STRING"))))
(hd 'a)
(println (mapcar char (in 'a (read7bitwise))))</lang>
{{out}}
<pre>00000000 FE 03 F8 0F E0 3F 80 FE .....?..
(127 0 127 0 127 0 127 0)
00000000 01 FC 07 F0 1F C0 7F 00 .......
(0 127 0 127 0 127 0 127)
00000000 A7 52 94 99 D1 C0 .R....
("S" "T" "R" "I" "N" "G")</pre>


=={{header|PureBasic}}==
=={{header|PureBasic}}==
Line 2,436: Line 2,416:
Decrunched string equal to original.
Decrunched string equal to original.
</pre>
</pre>

=={{header|Raku}}==
(formerly Perl 6)
<lang perl6>sub encode-ascii(Str $s) {
my @b = flat $s.ords».fmt("%07b")».comb;
@b.push(0) until @b %% 8; # padding
Buf.new: gather while @b { take reduce * *2+*, (@b.pop for ^8) }
}

sub decode-ascii(Buf $b) {
my @b = flat $b.list».fmt("%08b")».comb;
@b.shift until @b %% 7; # remove padding
@b = gather while @b { take reduce * *2+*, (@b.pop for ^7) }
return [~] @b».chr;
}
say my $encode = encode-ascii 'STRING';
say decode-ascii $encode;</lang>
{{out}}
<pre>Buf:0x<03 8b 99 29 4a e5>
STRING</pre>


=={{header|Red}}==
=={{header|Red}}==