Bitwise IO: Difference between revisions
Replace deprecated functions
Puppydrum64 (talk | contribs) |
(Replace deprecated functions) |
||
(14 intermediate revisions by 10 users not shown) | |||
Line 1:
{{task}}The aim of this task is to write functions (or create a class if your
language is Object Oriented and you prefer) for reading and writing sequences of
bits, most significant bit first. While the output of a <tt>asciiprint "STRING"</tt> is the ASCII byte sequence
Line 25:
{{trans|Python}}
<
accumulator = 0
bcount = 0
F (fname)
.out = File(fname,
F _writebit(bit)
Line 61:
F (fname)
.input = File(fname
F _readbit()
I .bcount == 0
V a = .input.read_bytes(at_most' 1)
I !a.empty
.accumulator = a[0]
Line 94:
L.break
charsa.append(Char(code' x))
print(charsa.join(‘’))</
{{out}}
Line 105:
This routine converts a byte to a sequence of ASCII zeroes and ones, and stores them in a null-terminated string. Works in Easy6502.
Multiple bytes can be stored this way simply by loading a new value in the accumulator and calling the subroutine again. Since Y is still pointed at the null terminator, no re-adjustment of <code>z_BC</code> or Y is necessary.
<
define StringRam $1200 ;not actually used in the code, but it's here for clarity.
define z_BC $00 ;fake Z80-style register for pseudo-16-bit operations.
Line 145:
lda #$00 ;load the null terminator
sta (z_BC),y ;store the null terminator after the string
rts</
{{out}}
Line 154:
===Compressing a String of ASCII Zeroes and Ones===
Building on the above, the process can be reversed. The output of the first function becomes the input of the second. Some of the above is repeated, this is to show the two working in sequence.
<
define BitRam $1400
define z_BC $00
Line 242:
;;;;;;;;;;;;;;;;;;;;;;;;;
Terminated:
rts</
{{out}}
<pre>
Line 249:
1400: 57 50
</pre>
=={{header|Ada}}==
<
with Ada.Finalization;
Line 270 ⟶ 269:
end record;
overriding procedure Finalize (Stream : in out Bit_Stream);
end Bit_Streams;</
The package provides a bit stream interface to a conventional stream. The object of Bit_Stream has a discriminant of any stream type. This stream will be used for physical I/O. Bit_Stream reads and writes arrays of bits. There is no need to have flush procedure, because this is done upon object destruction. The implementation is straightforward, big endian encoding of bits into Stream_Element units is used as required by the task:
<
procedure Finalize (Stream : in out Bit_Stream) is
begin
Line 304 ⟶ 303:
end loop;
end Write;
end Bit_Streams;</
Example of use:
<
with Bit_Streams; use Bit_Streams;
Line 338 ⟶ 337:
raise Data_Error;
end if;
end Test_Bit_Streams;</
=={{header|ALGOL 68}}==
{{works with|ALGOL 68|Revision 1 - no extensions to language used}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
<
MODE NIBBLE = STRUCT(INT width, BITS bits);
Line 474 ⟶ 472:
example uudecode nibble stream;
example uuencode nibble stream;
example compress 7bit chars</
{{out}}
<pre>
Line 492 ⟶ 490:
STRING & ABACUS => 101001110101001010010100100110011101000111010000001001100100000100000110000101000001100001110101011010011
</pre>
=={{header|AutoHotkey}}==
<
IfExist, %A_WorkingDir%\z.dat
FileDelete %file%
Line 619 ⟶ 616:
Totalread += 0 ; convert to original format
Return TotalRead
}</
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
test$ = "Hello, world!"
Line 665 ⟶ 661:
v% = v% << 1 OR (a% >> c%) AND 1
ENDWHILE
= v%</
{{out}}
<pre>
Hello, world!
</pre>
=={{header|Binary Lambda Calculus}}==
As explained on https://www.ioccc.org/2012/tromp/hint.html, BLC program
<pre>44 68 16 05 7e 01 17 00 be 55 ff f0 0d c1 8b b2 c1
b0 f8 7c 2d d8 05 9e 09 7f bf b1 48 39 ce 81 ce 80</pre>
compresses a string of ASCII "0"/"1" bytes into an 8x smaller stream of bytes, padding the final byte with 0 bits.
=={{header|C}}==
MSB in a byte is considered the "first" bit. Read and write methods somewhat mimic fread and fwrite, though there's no fflush-like function because flushing bits into a file is ill-defined (this whole task is pretty ill-defined). Only way to make sure all bits are written to the file is by detaching the bit filter, just like how closing a file flushes out buffer. There's no limit on read/write size, but caller should ensure the buffer is large enough.
<
#include <stdlib.h>
#include <stdint.h>
Line 786 ⟶ 787:
return 0;
}</
=={{header|C sharp|C#}}==
<
using System.IO;
Line 933 ⟶ 934:
reader.Align();
}
}</
=={{header|Common Lisp}}==
Common Lisp already has tonnes of bitwise-I/O functionality (remember, folks have written operating systems in Lisp …); in particular, READ-SEQUENCE and WRITE-SEQUENCE neatly handle dumping (VECTOR (UNSIGNED-BYTE 8)) objects directly to/from I/O streams with :ELEMENT-TYPE (UNSIGNED-BYTE 8). This is a fairly robust but not very optimized toolkit that shows off changing between vectors of bytes, vectors of characters, and bit-vectors in a few ways.
<
(defpackage :rosetta.bitwise-i/o
(:use :common-lisp)
Line 1,081:
(finish-output *trace-output*))
</syntaxhighlight>
{{out}}
<
BITWISE-I/O> (bitwise-i/o-demo)
Line 1,110:
⇒ ABORT
</syntaxhighlight>
=={{header|D}}==
{{trans|C}}
<
import core.stdc.stdio: FILE, fputc, fgetc;
import std.string: representation;
Line 1,246 ⟶ 1,245:
// Should be the same chars as 'data'.
result.assumeUTF.writeln;
}</
{{out}}
abcdefghijk
Line 1,253 ⟶ 1,252:
{{libheader| System.Classes}}
{{Trans|C#}}
<syntaxhighlight lang="delphi">
program Bitwise_IO;
Line 1,422 ⟶ 1,421:
reader.Free;
Readln;
end.</
{{out}}
<pre>
Line 1,429 ⟶ 1,428:
0x0155
</pre>
=={{header|Ecstasy}}==
<syntaxhighlight lang="java">
module BitwiseIO {
class BitReader {
construct(Byte[] bytes) {
this.bits = bytes.toBitArray();
}
private Bit[] bits;
private Int index;
Int offset { // readable & writable property "offset"
@Override
Int get() {
return index;
}
@Override
void set(Int offset) {
assert 0 <= offset < size;
index = offset;
}
}
Int size.get() { // read-only property "size"
return bits.size;
}
Boolean eof.get() { // read-only property "eof"
return index >= size;
}
Bit readBit() {
return eof ? assert:bounds : bits[index++];
}
Byte readByte() {
assert:bounds index + 8 <= size as $"eof (offset={index}, size={size}";
Int start = index;
index += 8;
return bits[start ..< index].toByte();
}
}
class BitWriter {
private Bit[] bits = new Bit[];
BitWriter writeBit(Bit bit) {
bits.add(bit);
return this;
}
BitWriter writeByte(Byte byte) {
bits.addAll(byte.toBitArray());
return this;
}
Byte[] bytes.get() {
// "zero fill" the bits to the next byte boundary: if the bits don't currently stop at
// a byte boundary, then calc the number of "extra" bits (bits.size & 0x7) and append
// "fill bits" from the end slice of the array of bits in the byte=0
bits += bits.size & 0x7 == 0 ? [] : Byte:0.toBitArray() [bits.size & 0x7 ..< 8];
return bits.toByteArray();
}
}
@Inject Console console;
void run() {
Bit[] orig = [0,1,0,1,0,1,1,1,0,1,0,1,0]; // hexadecimal 57 50 (with LSB padding)
val out = new BitWriter();
orig.forEach(bit -> out.writeBit(bit));
val bytes = out.bytes;
console.print($"bytes written={bytes}"); // 0x5750
val in = new BitReader(bytes);
val test = new Bit[orig.size]((Int i) -> in.readBit());
assert test == orig;
}
}
</syntaxhighlight>
=={{header|Erlang}}==
<
-compile([export_all]).
Line 1,483 ⟶ 1,565:
end,
Decompressed = decompress(Unpadded),
io:format("~p~n",[Decompressed]).</
{{out}}
<
<<"Hello, Rosetta Code!">>: 160
<<145,151,102,205,235,16,82,223,207,47,78,152,80,67,223,147,42,1:4>>: 140
Line 1,492 ⟶ 1,574:
ok
185> bitwise_io:test_file_io().
<<"Hello, Rosetta Code!">></
=={{header|Forth}}==
The stream status is kept on the stack ( b m ), where b is the character accumulator
Line 1,499 ⟶ 1,580:
with the MSB. (The writing code was originally used for Mandelbrot generation.)
<
: init-write ( -- b m ) 0 128 ;
Line 1,519 ⟶ 1,600:
: read-bit ( b m -- b' m' f )
dup 0= if 2drop init-read then
2dup and swap 2/ swap ;</
=={{header|FreeBASIC}}==
{{trans|Wren}}
<syntaxhighlight lang="vbnet">Type BitFilter
nombre As String
accu As Integer
bits As Integer
bw As Integer
br As Integer
offset As Integer
End Type
Sub openWriter(bf As BitFilter)
bf.bw = Freefile
Open bf.nombre For Binary Access Write As #bf.bw
End Sub
Sub openReader(bf As BitFilter)
bf.br = Freefile
Open bf.nombre For Binary Access Read As #bf.br
bf.offset = 0
End Sub
Sub escribe(bf As BitFilter, buf() As Byte, start As Integer, nBits As Integer, shift As Integer)
Dim As Integer index = start + (shift \ 8)
shift Mod= 8
While nBits <> 0 Or bf.bits >= 8
While bf.bits >= 8
bf.bits -= 8
Dim As Byte outByte = ((bf.accu Shr bf.bits) And &hFF)
Put #bf.bw, , outByte
Wend
While bf.bits < 8 And nBits <> 0
Dim As Byte b = buf(index)
bf.accu = (bf.accu Shl 1) Or (((128 Shr shift) And b) Shr (7 - shift))
nBits -= 1
bf.bits += 1
shift += 1
If shift = 8 Then
shift = 0
index += 1
End If
Wend
Wend
End Sub
Sub lee(bf As BitFilter, buf() As Byte, start As Integer, nBits As Integer, shift As Integer)
Dim As Integer index = start + (shift \ 8)
shift Mod= 8
While nBits <> 0
While bf.bits <> 0 And nBits <> 0
Dim As Byte mask = 128 Shr shift
buf(index) = Iif((bf.accu And (1 Shl (bf.bits - 1))) <> 0, (buf(index) Or mask) And &hFF, (buf(index) And Not mask) And &hFF)
nBits -= 1
bf.bits -= 1
shift += 1
If shift >= 8 Then
shift = 0
index += 1
End If
Wend
If nBits = 0 Then Exit Sub
Dim As Byte inByte
Get #bf.br, bf.offset + 1, inByte
bf.accu = (bf.accu Shl 8) Or inByte
bf.bits += 8
bf.offset += 1
Wend
End Sub
Sub closeWriter(bf As BitFilter)
If bf.bits <> 0 Then
bf.accu Shl= (8 - bf.bits)
Dim As Byte outByte = (bf.accu And &hFF)
Put #bf.bw, , outByte
End If
Close #bf.bw
bf.accu = 0
bf.bits = 0
End Sub
Sub closeReader(bf As BitFilter)
Close #bf.br
bf.accu = 0
bf.bits = 0
bf.offset = 0
End Sub
Dim As Integer i
Dim As BitFilter bf
bf.nombre = "test.bin"
' for each byte in s, write 7 bits skipping 1
Dim As Byte s(10) => {Asc("a"), Asc("b"), Asc("c"), Asc("d"), _
Asc("e"), Asc("f"), Asc("g"), Asc("h"), Asc("i"), Asc("j"), Asc("k")}
openWriter(bf)
For i = 0 To Ubound(s)
escribe(bf, s(), i, 7, 1)
Next i
closeWriter(bf)
' read 7 bits and expand to each byte of s2 skipping 1 bit
openReader(bf)
Dim As Byte s2(0 To Ubound(s)) = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
For i = 0 To Ubound(s2)
lee(bf, s2(), i, 7, 1)
Next i
closeReader(bf)
For i = 0 To Ubound(s2)
Print Chr(s2(i));
Next i
Print
Sleep</syntaxhighlight>
{{out}}
<pre>abcdefghijk</pre>
=={{header|Go}}==
Line 1,526 ⟶ 1,724:
encoder and decoder internal types
(with LZW specific stuff trimmed).
<
package bit
Line 1,728 ⟶ 1,926:
}
return br
}</
And a test file (such as <code>bit_test.go</code>):
<
import (
Line 1,794 ⟶ 1,992:
// Written bytes: A9 A3 4F 34 1A 79 A0 C2 83 A6 5E 7D 17 00
// Read back as "This is a test."
}</
With this test file, running <code>go test -v</code> will compile the package and run the example verifying the output is as listed above in the <code>// Output:</code> comments.
Additionally, <code>godoc -ex</code> will extract the code comments for documentation and include the examples at the appropriate place
(here the first goes with the <code>WriteBits</code> method and the later with the package documentation).
=={{header|Haskell}}==
<
import Data.Char
import Control.Monad
Line 1,829 ⟶ 2,026:
putStrLn $ "Compressed text has " ++ show (length bits `div` 8) ++ " bytes."
putStrLn "Read and decompress:"
putStrLn $ '\t' : bitReader bits</
* 7-bits code has lsb leading.
<pre>*Main> :main ["This text is used to illustrate the Rosetta Code task 'bit oriented IO'."]
Line 1,838 ⟶ 2,035:
Read and decompress:
This text is used to illustrate the Rosetta Code task 'bit oriented IO'.</pre>
=={{header|J}}==
;Solution
<
bitWriter =: , @ ((7$2) & #: @ (a.&i.)), 0 $~ 8 | #</
;Usage
Do and undo bit oriented IO:
<
bitReader bitWriter text
This text is used to illustrate the Rosetta Code task about 'bit oriented IO'.</
Original text length:
<
78</
Note: '#' here counts the number of items in its right argument. (In some other languages, # marks the beginning of an in-line comment. J is not one of those languages. Also note that J's command prompt is three spaces. This makes copy&paste easier to use with previously issued commands.)
Compressed length:
<
69</
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}}==
ASCII 7-bit character string compression and decompression, to demonstrate bit twiddling. Implemented as generic IO, so that file handles are usable with the same functions.
<syntaxhighlight lang="julia">
function compress7(inio, outio)
nextwritebyte = read(inio, UInt8) & 0x7f
Line 1,910 ⟶ 2,105:
println("Compressed to length $(length(outs.data)) on line below:\n", String(outs.data))
println("Decompressed string: ", String(newouts.data))
</
Initial string of length 88: These bit oriented I/O functions can be used to implement compressors and decompressors.
Compressed to length 77 on line below:
Line 1,916 ⟶ 2,111:
Decompressed string: These bit oriented I/O functions can be used to implement compressors and decompressors.
</pre>
=={{header|Kotlin}}==
{{trans|C}}
<
import java.io.File
Line 2,002 ⟶ 2,196:
bf.closeReader()
println(String(s2, Charsets.UTF_8))
}</
{{out}}
Line 2,008 ⟶ 2,202:
abcdefghijk
</pre>
=={{header|Lingo}}==
A "BitArray" class can be implemented by sub-classing ByteArray and extending it with methods that allow to get/set individual bits:
<
property ancestor
Line 2,073 ⟶ 2,266:
delete the last char of res
return res
end</
Simple compression/decompression functions for 7-bit ASCII strings:
<
-- @param {string} str - ASCII string
-- @return {instance} BitArray
Line 2,112 ⟶ 2,305:
end repeat
return str
end</
<
ba = crunchASCII(str)
Line 2,124 ⟶ 2,317:
put decrunchASCII(ba)
-- "ABC"</
=={{header|Lua}}==
{{works with|Lua|5.1 and later, including LuaJIT}}
This code defines two functions that return objects for reading and writing bits from/to strings.
<syntaxhighlight lang="lua">local function BitWriter() return {
accumulator = 0, -- For current byte.
bitCount = 0, -- Bits set in current byte.
outChars = {},
-- writer:writeBit( bit )
writeBit = function(writer, bit)
writer.bitCount = writer.bitCount + 1
if bit > 0 then
writer.accumulator = writer.accumulator + 2^(8-writer.bitCount)
end
if writer.bitCount == 8 then
writer:_flush()
end
end,
-- writer:writeLsb( value, width )
writeLsb = function(writer, value, width)
for i = 1, width do
writer:writeBit(value%2)
value = math.floor(value/2)
end
end,
-- dataString = writer:getOutput( )
getOutput = function(writer)
writer:_flush()
return table.concat(writer.outChars)
end,
_flush = function(writer)
if writer.bitCount == 0 then return end
table.insert(writer.outChars, string.char(writer.accumulator))
writer.accumulator = 0
writer.bitCount = 0
end,
} end
local function BitReader(data) return {
bitPosition = 0, -- Absolute position in 'data'.
-- bit = reader:readBit( ) -- Returns nil at end-of-data.
readBit = function(reader)
reader.bitPosition = reader.bitPosition + 1
local bytePosition = math.floor((reader.bitPosition-1)/8) + 1
local byte = data:byte(bytePosition)
if not byte then return nil end
local bitIndex = ((reader.bitPosition-1)%8) + 1
return math.floor(byte / 2^(8-bitIndex)) % 2
end,
-- value = reader:readLsb( width ) -- Returns nil at end-of-data.
readLsb = function(reader, width)
local accumulator = 0
for i = 1, width do
local bit = reader:readBit()
if not bit then return nil end
if bit > 0 then
accumulator = accumulator + 2^(i-1)
end
end
return accumulator
end,
} end</syntaxhighlight>
Test writing and reading back 7-bit ASCII characters.
<syntaxhighlight lang="lua">-- Test writing.
local writer = BitWriter()
local input = "Beautiful moon!"
for i = 1, #input do
writer:writeLsb(input:byte(i), 7)
end
local data = writer:getOutput() -- May include padding at the end.
-- Test reading.
local reader = BitReader(data)
local chars = {}
for i = 1, #input do -- Assume the amount of characters is the same as when we wrote the data.
chars[i] = string.char(reader:readLsb(7))
end
local output = table.concat(chars)
-- Show results.
local hexToBin = {["0"]="0000",["1"]="0001",["2"]="0010",["3"]="0011",
["4"]="0100",["5"]="0101",["6"]="0110",["7"]="0111",
["8"]="1000",["9"]="1001",["a"]="1010",["b"]="1011",
["c"]="1100",["d"]="1101",["e"]="1110",["f"]="1111"}
local function charToHex(c)
return string.format("%02x", c:byte())
end
local function formatBinary(data)
return (data:gsub(".", charToHex)
:gsub(".", hexToBin)
:gsub("........", "%0 "))
end
print("In: "..input)
print("Out: "..output)
print("Data: "..formatBinary(data))</syntaxhighlight>
{{out}}
<pre>
In: Beautiful moon!
Out: Beautiful moon!
Data: 01000011 01001110 00011101 01110010 11110010 11011001 11010111 00110110 00001010 11011111 10111111 01101110 11100001 00000000
</pre>
=={{header|MIPS Assembly}}==
See [[Bitwise IO/MIPS Assembly]]
=={{header|Nim}}==
<
BitWriter * = tuple
file: File
Line 2,226 ⟶ 2,541:
file.close
echo "OK"</
=={{header|OCaml}}==
The [http://code.google.com/p/ocaml-extlib/ extLib] provides [http://ocaml-extlib.googlecode.com/svn/doc/apiref/IO.html#6_BitsAPI bit oriented IO functions].
<
let oc = open_out filename in
let ob = IO.output_bits(IO.output_channel oc) in
Line 2,236 ⟶ 2,550:
IO.flush_bits ob;
close_out oc;
;;</
<
let ic = open_in filename in
let ib = IO.input_bits(IO.input_channel ic) in
Line 2,247 ⟶ 2,561:
done; ""
with IO.No_more_input ->
(Buffer.contents buf)</
=={{header|Perl}}==
<syntaxhighlight lang
# $buffer = write_bits(*STDOUT, $buffer, $number, $bits)
sub write_bits :prototype( $$$$ )
{
my ($out, $l, $num, $q) = @_;
Line 2,269 ⟶ 2,580:
# flush_bits(*STDOUT, $buffer)
sub flush_bits :prototype( $$ )
{
my ($out, $b) = @_;
Line 2,276 ⟶ 2,587:
# ($val, $buf) = read_bits(*STDIN, $buf, $n)
sub read_bits :prototype( $$$ )
{
my ( $in, $b, $n ) = @_;
Line 2,293 ⟶ 2,604:
$b = substr($b, $n);
return ($val, $b);
}</
''Crunching'' bytes discarding most significant bit (lossless compression for ASCII and few more!)
<
my $c;
while( read(*STDIN, $c, 1) > 0 ) {
$buf = write_bits(*STDOUT, $buf, unpack("C1", $c), 7);
}
flush_bits(*STDOUT, $buf);</
Expanding each seven bits to fit a byte (padding the ''eight'' most significant bit with 0):
<
my $v;
while(1) {
Line 2,308 ⟶ 2,619:
last if ($buf < 0);
print pack("C1", $v);
}</
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (file i/o)</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">FN</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">V</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">BITS</span> <span style="color: #000080;font-style:italic;">-- fields of a bitwiseioreader/writer</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">new_bitwiseio</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mode</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mode</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}</span> <span style="color: #000080;font-style:italic;">-- ie {FN,V=0,BITS=0}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">new_bitwiseiowriter</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">filename</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">new_bitwiseio</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"wb"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">new_bitwiseioreader</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">filename</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">new_bitwiseio</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"rb"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">write_bits</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">writer</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">bits</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wv</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wb</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">writer</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">p2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bits</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">ch</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">!=</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">wv</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">wv</span><span style="color: #0000FF;">*</span><span style="color: #000000;">p2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">v</span>
<span style="color: #000000;">wb</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">bits</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">wb</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">wb</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">8</span>
<span style="color: #000000;">p2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wb</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">wv</span><span style="color: #0000FF;">/</span><span style="color: #000000;">p2</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">wv</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">*</span><span style="color: #000000;">p2</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">wv</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">#100</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">wb</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">8</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">writer</span><span style="color: #0000FF;">[</span><span style="color: #000000;">V</span><span style="color: #0000FF;">]=</span> <span style="color: #000000;">wv</span>
<span style="color: #000000;">writer</span><span style="color: #0000FF;">[</span><span style="color: #000000;">BITS</span><span style="color: #0000FF;">]=</span> <span style="color: #000000;">wb</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">writer</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">close_bitwiseiowriter</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">writer</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wv</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wb</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">writer</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">wb</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">wb</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">8</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- sanity check</span>
<span style="color: #000000;">writer</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">write_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">writer</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">-</span><span style="color: #000000;">wb</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">writer</span><span style="color: #0000FF;">[</span><span style="color: #000000;">V</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">writer</span><span style="color: #0000FF;">[</span><span style="color: #000000;">BITS</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">writer</span><span style="color: #0000FF;">[</span><span style="color: #000000;">FN</span><span style="color: #0000FF;">]=-</span><span style="color: #000000;">1</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">writer</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">read_bits</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">reader</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">bits</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rv</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rb</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">reader</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">p2</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">bits</span><span style="color: #0000FF;">></span><span style="color: #000000;">rb</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">reader</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">rv</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rv</span><span style="color: #0000FF;">*</span><span style="color: #000000;">#100</span><span style="color: #0000FF;">+</span><span style="color: #000000;">ch</span>
<span style="color: #000000;">rb</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">8</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">rb</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">bits</span>
<span style="color: #000000;">p2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rb</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rv</span><span style="color: #0000FF;">/</span><span style="color: #000000;">p2</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">rv</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">*</span><span style="color: #000000;">p2</span>
<span style="color: #000000;">reader</span><span style="color: #0000FF;">[</span><span style="color: #000000;">V</span><span style="color: #0000FF;">]=</span> <span style="color: #000000;">rv</span>
<span style="color: #000000;">reader</span><span style="color: #0000FF;">[</span><span style="color: #000000;">BITS</span><span style="color: #0000FF;">]=</span> <span style="color: #000000;">rb</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">reader</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">as_hexb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">fmt</span><span style="color: #0000FF;">=</span><span style="color: #008000;">"%02x "</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- helper funtion, returns hex string, or binary if fmt="%08b "</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">test</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"This is a test."</span>
<span style="color: #000080;font-style:italic;">--constant test = "
--constant test = "
--constant test = "STRING"
--constant test = "This is an ascii string that will be crunched, written, read and expanded."</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\"%s\" as bytes: %s (length %d)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">test</span><span style="color: #0000FF;">,</span><span style="color: #000000;">as_hexb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">)})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" original bits: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">as_hexb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%08b "</span><span style="color: #0000FF;">)})</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">writer</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">new_bitwiseiowriter</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"test.bin"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">writer</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">write_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">writer</span><span style="color: #0000FF;">,</span><span style="color: #000000;">test</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">7</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">writer</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">close_bitwiseiowriter</span><span style="color: #0000FF;">(</span><span style="color: #000000;">writer</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"test.bin"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"rb"</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">bytes</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_text</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #004600;">GT_WHOLE_FILE</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Written bitstream: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">as_hexb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bytes</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%08b "</span><span style="color: #0000FF;">)})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Written bytes: %s (length %d)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">as_hexb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bytes</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bytes</span><span style="color: #0000FF;">)})</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">reader</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">new_bitwiseioreader</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"test.bin"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">bytes</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">reader</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">read_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">reader</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">bytes</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">ch</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\"%s\" as bytes: %s (length %d)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">bytes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">as_hexb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bytes</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bytes</span><span style="color: #0000FF;">)})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,426 ⟶ 2,740:
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.
=={{header|PicoLisp}}==
<
(let (Bits 0 Byte)
(for N Lst
Line 2,449 ⟶ 2,762:
(setq Byte (& 127 (>> (- Bits 7) N))) ) )
(when (= 7 Bits)
(link Byte) ) ) ) )</
<
(hd 'a)
(in 'a (println (read7bitwise)))
Line 2,460 ⟶ 2,773:
(out 'a (write7bitwise (mapcar char (chop "STRING"))))
(hd 'a)
(println (mapcar char (in 'a (read7bitwise))))</
{{out}}
<pre>00000000 FE 03 F8 0F E0 3F 80 FE .....?..
Line 2,468 ⟶ 2,781:
00000000 A7 52 94 99 D1 C0 .R....
("S" "T" "R" "I" "N" "G")</pre>
=={{header|PL/I}}==
<
on endfile (sysin) go to ending;
bs = ''b;
Line 2,480 ⟶ 2,792:
bs = bs || copy('0'b, mod(length(bs), 8) );
/* pad length to a multiple of 8 */
put edit (bs) (b);</
Example:
<pre>
Line 2,512 ⟶ 2,824:
1010011101010010100101001001100111010001111010011000110100010100000000
</pre>
=={{header|PureBasic}}==
The bits are read/written with the HSB being read/written first, then each full byte (8 bits) is read/written in succession. Depending on the native integer size the compiler is using, upto 32-bits or 64-bits can be read/written at once. The procedure flushBits() should be called when the reading/writing of bits is completed. If a partial byte is written the bits containing data will begin with the HSB and the padding bits will end with the LSB.
As a slight speed modification, the readBits() and writeBits() procedures will attempt to write groups of bits whenever possible.
<
bitsToWrite.i
bitsToRead.i
Line 2,636 ⟶ 2,947:
result + "Expanded string = '" + testReadString + "'"
MessageRequester("Results", result)</
{{out}}
<pre>Original ascii string is 74 bytes.
Line 2,642 ⟶ 2,953:
The expanded string is the same as the original.
Expanded string = 'This is an ascii string that will be crunched, written, read and expanded.'</pre>
=={{header|Python}}==
This following code works in both Python 2 & 3. Suggested module file name <tt>bitio.py</tt>.
<
def __init__(self, f):
self.accumulator = 0
Line 2,734 ⟶ 3,044:
chars.append(chr(x))
print(''.join(chars))
</syntaxhighlight>
Another usage example showing how to "crunch" an 8-bit byte ASCII stream discarding the most significant "unused" bit...and read it back.
<
import bitio
Line 2,745 ⟶ 3,055:
c = sys.stdin.read(1)
o.flush()
</syntaxhighlight>
...and to "decrunch" the same stream:
<
import bitio
Line 2,755 ⟶ 3,065:
if not r.read: # nothing read
break
sys.stdout.write(chr(x))</
=={{header|Racket}}==
<
#lang racket
Line 2,819 ⟶ 3,128:
(printf "Decrunched string ~aequal to original.\n"
(if (equal? orig (decrunch "crunched.out")) "" "NOT "))
</syntaxhighlight>
{{out}}
Line 2,825 ⟶ 3,134:
Decrunched string equal to original.
</pre>
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku"
my @b = flat $s.ords».fmt("%07b")».comb;
@b.push(0) until @b %% 8; # padding
Line 2,841 ⟶ 3,149:
}
say my $encode = encode-ascii 'STRING';
say decode-ascii $encode;</
{{out}}
<pre>Buf:0x<03 8b 99 29 4a e5>
STRING</pre>
=={{header|Red}}==
<
Title: "Bitwise IO"
Link: http://rosettacode.org/wiki/Bitwise_IO
Line 2,905 ⟶ 3,212:
pad "Expanded (string): " 20 mold to-string expanded
]
</syntaxhighlight>
{{out}}
Line 2,919 ⟶ 3,226:
Expanded (string): "Red forever!"
</pre>
=={{header|REXX}}==
===version 1===
<
* 01.11.2012 Walter Pachl
***********************************************************************/
Line 2,947 ⟶ 3,253:
r=r||x2c(x) /* convert to character */
End /* and append to result */
Say 'r='r /* show result */</
{{out}}
<pre>
Line 2,957 ⟶ 3,263:
===version 2===
<
parse arg $; if $=='' then $= 'STRING' /*get optional argument; Use default ? */
say ' input string=' $ /*display the input string to terminal.*/
Line 2,970 ⟶ 3,276:
dcomp: parse arg x; z=; do k=1 by 7 to length(x); _= substr(x, k, 7)
if right(_, 1)==' ' then leave; z= z || x2c( b2x(0 || _) )
end /*k*/; return z</
{{out|output|text= when using the default input:}}
<pre>
Line 2,977 ⟶ 3,283:
decoded string= STRING
</pre>
=={{header|Ruby}}==
{{trans|Tcl}}
{{works with|Ruby|1.8.7}}
<
bitstring = ascii.bytes.collect {|b| "%07b" % b}.join
[bitstring].pack("B*")
Line 3,015 ⟶ 3,320:
else
puts "fail!"
end</
=={{header|Rust}}==
The implementation accepts the number of bits to discard/expand as an argument.
<
type Output: Iterator<Item = u8>;
Line 3,180 ⟶ 3,484:
let decompressed = process_bytes(BitExpand::new(discard), &compressed);
print_bytes(&decompressed);
}</
=={{header|Seed7}}==
The Seed7 library [
several functions to do bitwise I/O. Bitwise data can be read from (or written to) a string or a file.
The direction of bits can be from LSB (least significant bit) to MSB (most significant bit) or vice versa.
In the program below the functions
[
<
include "bitdata.s7i";
include "strifile.s7i";
Line 3,214 ⟶ 3,517:
const proc: finishWriteAscii (inout file: outFile, inout integer: bitPos) is func
begin
putBitsMsb(outFile, bitPos, 0, 7); # Write a terminating NUL char.
write(outFile, chr(ord(outFile.bufferChar)));
end func;
const
result
var string: stri is "";
Line 3,228 ⟶ 3,527:
var char: ch is ' ';
begin
while
ch := chr(
if
stri &:= ch;
end if;
Line 3,240 ⟶ 3,539:
var file: aFile is STD_NULL;
var integer: bitPos is 0;
var msbBitStream: aBitStream is msbBitStream.value;
begin
aFile :=
initWriteAscii(aFile, bitPos);
writeAscii(aFile, bitPos, "Hello, Rosetta Code!");
finishWriteAscii(aFile, bitPos);
seek(aFile, 1);
writeln(literal(readAscii(
end func;</
{{out}}
Line 3,256 ⟶ 3,556:
=={{header|Tcl}}==
<
proc crunch {ascii} {
Line 3,303 ⟶ 3,603:
} else {
error "not the same"
}</
{{out}}
<pre>my ascii string is 74 bytes
the file containing the crunched text is 65 bytes
the expanded string is the same as the original</pre>
=={{header|Wren}}==
{{trans|Kotlin}}
<
class BitFilter {
Line 3,410 ⟶ 3,709:
for (i in 0...s2.count) bf.read(s2, i, 7, 1)
bf.closeReader()
System.print(s2.map { |b| String.fromByte(b) }.join())</
{{out}}
Line 3,420 ⟶ 3,719:
===Uncompressing Packed Bytes into ASCII Zeroes and Ones===
Code is optimized to use what I call a "revolving bit mask" since there is no way to iterate through <code>BIT</code> commands without self-modifying code which is even more difficult to read in my opinion. Using <code>BIT</code> tests without self-modifying code would require the loop to be unrolled.
<syntaxhighlight lang="z80">StoreBinaryString:
;INPUT:
; HL = SOURCE ADDRESS
Line 3,448 ⟶ 3,748:
or c
jp nz,StoreBinaryString
ret</
{{out}}
<pre>
Line 3,458 ⟶ 3,758:
===Compressing a String of ASCII Zeroes and Ones===
<
; HL = pointer to output
; DE = pointer to input. Input is assumed to equal &30 or &31
Line 3,498 ⟶ 3,798:
rlc (hl)
z_djnz loop_earlyExit
ret</
{{out}}
Line 3,506 ⟶ 3,806:
57 50
</pre>
=={{header|zkl}}==
This code implements two state machines: one that transforms a bit stream (ie a stream of ints with a maximum number of bits) to a byte stream and one does the reverse transform. All streams are considered infinite (eg a file or socket).
Bits to bytes:
<
fcn toBytes(n,[(numBits,acc,bitsSoFar)]state){
acc=acc.shiftLeft(numBits) + n; bitsSoFar+=numBits;
Line 3,523 ⟶ 3,822:
state.clear(numBits,acc,bitsSoFar);
r
}</
Encode a stream of 6 bit characters:
<
ns.println(ns.len());
Line 3,531 ⟶ 3,830:
cns:=ns.pump(List,toBytes.fp1(state)); // List could be a file or socket or ...
if(state[2]) cns+=toBytes(0,state); // flush
cns.println(cns.len());</
{{out}}
<pre>
Line 3,538 ⟶ 3,837:
</pre>
Byte stream to bit stream:
<
fcn fromBytes(n,[(numBits,acc,bitsSoFar,buf)]state){
acc=acc.shiftLeft(8) + n; bitsSoFar+=8;
Line 3,549 ⟶ 3,848:
state.clear(numBits,acc,bitsSoFar,buf);
return(Void.Write,Void.Write,buf); // append contents of buf to result
}</
Decode the above stream:
<
r:=cns.pump(List,fromBytes.fp1(state)); // cns could be a file or ...
r.println(r.len());
r.pump(String,'+(0x20),"toChar").println();</
{{out}}
<pre>
Line 3,560 ⟶ 3,859:
THIS IS A TEST
</pre>
{{omit from|AWK|Traditional AWK has no bitwise operators}}
{{omit from|gnuplot}}
|