Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
4
Task/Bitwise-IO/00-META.yaml
Normal file
4
Task/Bitwise-IO/00-META.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category:
|
||||
- Bitwise operations
|
||||
from: http://rosettacode.org/wiki/Bitwise_IO
|
||||
22
Task/Bitwise-IO/00-TASK.txt
Normal file
22
Task/Bitwise-IO/00-TASK.txt
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
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
|
||||
"S", "T", "R", "I", "N", "G", the output of a "print" of the bits sequence
|
||||
0101011101010 (13 bits) must be 0101011101010; real I/O is performed always
|
||||
''quantized'' by byte (avoiding endianness issues and relying on underlying
|
||||
buffering for performance), therefore you must obtain as output the bytes
|
||||
0101 0111 0101 0'''000''' (bold bits are padding bits), i.e. in hexadecimal 57 50.
|
||||
|
||||
As test, you can implement a '''rough''' (e.g. don't care about error handling or
|
||||
other issues) compression/decompression program for ASCII sequences
|
||||
of bytes, i.e. bytes for which the most significant bit is always unused, so that you can write
|
||||
seven bits instead of eight (each 8 bytes of input, we write 7 bytes of output).
|
||||
|
||||
These bit oriented I/O functions can be used to implement compressors and
|
||||
decompressors; e.g. Dynamic and Static Huffman encodings use variable length
|
||||
bits sequences, while LZW (see [[LZW compression]]) use fixed or variable ''words''
|
||||
nine (or more) bits long.
|
||||
|
||||
* Limits in the maximum number of bits that can be written/read in a single read/write operation are allowed.
|
||||
* Errors handling is not mandatory
|
||||
<br><br>
|
||||
70
Task/Bitwise-IO/11l/bitwise-io.11l
Normal file
70
Task/Bitwise-IO/11l/bitwise-io.11l
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
T BitWriter
|
||||
File out
|
||||
accumulator = 0
|
||||
bcount = 0
|
||||
|
||||
F (fname)
|
||||
.out = File(fname, ‘w’)
|
||||
|
||||
F _writebit(bit)
|
||||
I .bcount == 8
|
||||
.flush()
|
||||
I bit > 0
|
||||
.accumulator [|]= 1 << (7 - .bcount)
|
||||
.bcount++
|
||||
|
||||
F writebits(bits, =n)
|
||||
L n > 0
|
||||
._writebit(bits [&] 1 << (n - 1))
|
||||
n--
|
||||
|
||||
F flush()
|
||||
.out.write_bytes([Byte(.accumulator)])
|
||||
.accumulator = 0
|
||||
.bcount = 0
|
||||
|
||||
F close()
|
||||
.flush()
|
||||
.out.close()
|
||||
|
||||
T BitReader
|
||||
File input
|
||||
accumulator = 0
|
||||
bcount = 0
|
||||
read = 0
|
||||
|
||||
F (fname)
|
||||
.input = File(fname, ‘r’)
|
||||
|
||||
F _readbit()
|
||||
I .bcount == 0
|
||||
V a = .input.read_bytes(1)
|
||||
I !a.empty
|
||||
.accumulator = a[0]
|
||||
.bcount = 8
|
||||
.read = a.len
|
||||
V rv = (.accumulator [&] (1 << (.bcount - 1))) >> (.bcount - 1)
|
||||
.bcount--
|
||||
R rv
|
||||
|
||||
F readbits(=n)
|
||||
V v = 0
|
||||
L n > 0
|
||||
v = (v << 1) [|] ._readbit()
|
||||
n--
|
||||
R v
|
||||
|
||||
V writer = BitWriter(‘bitio_test.dat’)
|
||||
V chars = ‘12345abcde’
|
||||
L(ch) chars
|
||||
writer.writebits(ch.code, 7)
|
||||
writer.close()
|
||||
|
||||
V reader = BitReader(‘bitio_test.dat’)
|
||||
[Char] charsa
|
||||
L
|
||||
V x = reader.readbits(7)
|
||||
I reader.read == 0
|
||||
L.break
|
||||
charsa.append(Char(code' x))
|
||||
print(charsa.join(‘’))
|
||||
40
Task/Bitwise-IO/6502-Assembly/bitwise-io-1.6502
Normal file
40
Task/Bitwise-IO/6502-Assembly/bitwise-io-1.6502
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
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.
|
||||
define z_C $00 ;6502 uses the low byte as the reference point for indirect lookups.
|
||||
define z_B $01 ;high byte
|
||||
define tempMath $02 ;temp storage of input
|
||||
define tempBitMask $03 ;temp storage of the bit filter
|
||||
|
||||
lda #$12
|
||||
sta z_B
|
||||
lda #$00
|
||||
sta z_C ;load address $1200 into zero page memory for an indirect lookup.
|
||||
|
||||
lda #$0F ;test value
|
||||
LDY #0 ;initialize offset to zero
|
||||
|
||||
jsr Hex2BinAscii
|
||||
brk ;on easy6502 this terminates the program.
|
||||
|
||||
Hex2BinAscii:
|
||||
sta tempMath ;store our input, in this case #$0F
|
||||
lda #%10000000
|
||||
sta tempBitMask
|
||||
|
||||
loop_Hex2BinAscii:
|
||||
lda tempMath ;load input into accumulator.
|
||||
and tempBitMask ;filter out all bits except the one we are checking this pass of the loop
|
||||
bne bitIsOne
|
||||
lda #$30 ;ascii for zero
|
||||
bne StoreBit
|
||||
bitIsOne:
|
||||
lda #$31 ;ascii for one
|
||||
StoreBit:
|
||||
sta (z_BC),y ;store in StringRam+Y
|
||||
loopOverhead:
|
||||
iny ;y++
|
||||
lsr tempBitMask ;shift to next bit in sequence
|
||||
beq loop_Hex2BinAscii ;if mask is zero, we are done. BCC would have worked here as well.
|
||||
lda #$00 ;load the null terminator
|
||||
sta (z_BC),y ;store the null terminator after the string
|
||||
rts
|
||||
89
Task/Bitwise-IO/6502-Assembly/bitwise-io-2.6502
Normal file
89
Task/Bitwise-IO/6502-Assembly/bitwise-io-2.6502
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
define StringRam $1200
|
||||
define BitRam $1400
|
||||
define z_BC $00
|
||||
define z_C $00
|
||||
define z_B $01
|
||||
define z_DE $02
|
||||
define z_E $02
|
||||
define z_D $03
|
||||
define tempMath $04
|
||||
define tempBitMask $05
|
||||
define tempY $06
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
LDA #0
|
||||
TAX
|
||||
TAY ;clear data regs (not needed on Easy6502 but it's a good practice at the start of a program on real hardware)
|
||||
|
||||
loop_clearRam:
|
||||
STA $1200,x
|
||||
STA $1400,x
|
||||
inx
|
||||
bne loop_clearRam
|
||||
|
||||
lda #$12
|
||||
sta z_B
|
||||
lda #$00
|
||||
sta z_C
|
||||
|
||||
lda #$57
|
||||
jsr Hex2BinAscii ;store first string
|
||||
|
||||
lda #$50
|
||||
jsr Hex2BinAscii ; store second string
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
LDA #$12
|
||||
STA z_B
|
||||
LDA #$00
|
||||
STA z_C ; get address of string Ram (this step isn't necessary as they're already loaded but it's here for clarity)
|
||||
|
||||
LDA #$14
|
||||
STA z_D
|
||||
LDA #$00
|
||||
STA z_E ; get address of destination
|
||||
|
||||
LDY #$00
|
||||
STY tempY ; the indices into StringRam and BitRam are different.
|
||||
|
||||
jsr CompressBits
|
||||
brk
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Hex2BinAscii:
|
||||
; this procedure is the same as the above example.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
CompressBits:
|
||||
; takes a stream of ascii zeroes and ones,
|
||||
; and packs them into a series of bytes.
|
||||
|
||||
LDX #8 ; repeat 8 times.
|
||||
LDA #0
|
||||
STA tempMath ;zero out tempMath
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
loop_CompressBits:
|
||||
LDA (z_BC),y
|
||||
beq Terminated ; if the value read is equal to the null terminator, we are done.
|
||||
; value is assumed to equal #$30 for 0 or #$31 for 1.
|
||||
ror ; bottom bit of accumulator is rotated into the carry flag.
|
||||
rol tempMath ; the carry is shifted into the bottom of tempMath.
|
||||
; repeating this with each successive ascii bit representation
|
||||
; will preserve the order of the bits. It's hard to explain without drawing a picture
|
||||
; but trust me it just works.
|
||||
iny ; next Y
|
||||
dex
|
||||
bne loop_CompressBits
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; loop overhead
|
||||
tya
|
||||
pha ; backup source index.
|
||||
ldy tempY
|
||||
lda tempMath
|
||||
sta (z_DE),y
|
||||
inc tempY ; increment destination index
|
||||
pla
|
||||
tay ; restore source index
|
||||
jmp CompressBits ; back to top
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Terminated:
|
||||
rts
|
||||
131
Task/Bitwise-IO/ALGOL-68/bitwise-io.alg
Normal file
131
Task/Bitwise-IO/ALGOL-68/bitwise-io.alg
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
# NIBBLEs are of any width, eg 1-bit OR 4-bits etc. #
|
||||
MODE NIBBLE = STRUCT(INT width, BITS bits);
|
||||
|
||||
PRIO << = 8, >> = 8; # define C style shift opertors #
|
||||
OP << = (BITS bits, INT shift)BITS: bits SHL shift;
|
||||
OP >> = (BITS bits, INT shift)BITS: bits SHR shift;
|
||||
|
||||
# define nibble opertors for left/right shift and append #
|
||||
OP << = (NIBBLE nibble, INT shift)NIBBLE:
|
||||
(width OF nibble + shift, bits OF nibble << shift);
|
||||
|
||||
OP >> = (NIBBLE nibble, INT shift)NIBBLE:
|
||||
(width OF nibble - shift, bits OF nibble >> shift);
|
||||
|
||||
OP +:= = (REF NIBBLE lhs, NIBBLE rhs)REF NIBBLE: (
|
||||
BITS rhs mask := BIN(ABS(2r1 << width OF rhs)-1);
|
||||
lhs := ( width OF lhs + width OF rhs, bits OF lhs << width OF rhs OR bits OF rhs AND rhs mask)
|
||||
);
|
||||
|
||||
# define MODEs for generating NIBBLE streams and yielding NIBBLEs #
|
||||
MODE YIELDNIBBLE = PROC(NIBBLE)VOID;
|
||||
MODE GENNIBBLE = PROC(YIELDNIBBLE)VOID;
|
||||
|
||||
PROC gen resize nibble = (
|
||||
INT out width,
|
||||
GENNIBBLE gen nibble,
|
||||
YIELDNIBBLE yield
|
||||
)VOID:(
|
||||
NIBBLE buf := (0, 2r0), out;
|
||||
BITS out mask := BIN(ABS(2r1 << out width)-1);
|
||||
# FOR NIBBLE nibble IN # gen nibble( # ) DO #
|
||||
## (NIBBLE in nibble)VOID:(
|
||||
buf +:= in nibble;
|
||||
WHILE width OF buf >= out width DO
|
||||
out := buf >> ( width OF buf - out width);
|
||||
width OF buf -:= out width; # trim 'out' from buf #
|
||||
yield((out width, bits OF out AND out mask))
|
||||
OD
|
||||
# OD # ))
|
||||
);
|
||||
|
||||
# Routines for joining strings and generating a stream of nibbles #
|
||||
|
||||
PROC gen nibble from 7bit chars = (STRING string, YIELDNIBBLE yield)VOID:
|
||||
FOR key FROM LWB string TO UPB string DO yield((7, BIN ABS string[key])) OD;
|
||||
|
||||
PROC gen nibble from 8bit chars = (STRING string, YIELDNIBBLE yield)VOID:
|
||||
FOR key FROM LWB string TO UPB string DO yield((8,BIN ABS string[key])) OD;
|
||||
|
||||
PROC gen join = ([]STRING strings, STRING new line, YIELDNIBBLE yield)VOID:
|
||||
FOR key FROM LWB strings TO UPB strings DO
|
||||
gen nibble from 8bit chars(strings[key]+new line, yield)
|
||||
OD;
|
||||
|
||||
# Two tables for uuencoding 6bits in printable ASCII chacters #
|
||||
|
||||
[0:63]CHAR encode uue 6bit:= # [0:63] => CHAR64 #
|
||||
"`!""#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_"[@0];
|
||||
|
||||
[0:255]BITS decode uue 6bit; # CHAR64 => [0:63] #
|
||||
FOR key FROM LWB encode uue 6bit TO UPB encode uue 6bit DO
|
||||
decode uue 6bit[ABS encode uue 6bit[key]] := BIN key
|
||||
OD;
|
||||
decode uue 6bit[ABS " "] := 2r0; # extra #
|
||||
|
||||
# Some basic examples #
|
||||
|
||||
PROC example uudecode nibble stream = VOID:(
|
||||
|
||||
[]STRING encoded uue 6bit hello world = (
|
||||
":&5L;&\L('=O<FQD""DAE;&QO+""!W;W)L9""$*1V]O9&)Y92P@8W)U96P@=V]R",
|
||||
";&0*22=M(&QE879I;F<@>6]U('1O9&%Y""D=O;V1B>64L(&=O;V1B>64L(&=O",
|
||||
";V1B>64@""@``"
|
||||
);
|
||||
|
||||
PROC gen join hello world = (YIELDNIBBLE yield)VOID:
|
||||
# FOR NIBBLE nibble IN # gen join(encoded uue 6bit hello world, "", # ) DO #
|
||||
## (NIBBLE nibble)VOID:(
|
||||
yield((6, decode uue 6bit[ABS bits OF nibble]))
|
||||
# OD # ));
|
||||
|
||||
print(("Decode uue 6bit NIBBLEs into 8bit CHARs:", new line));
|
||||
|
||||
# FOR NIBBLE nibble IN # gen resize nibble(8, gen join hello world, # ) DO ( #
|
||||
## (NIBBLE nibble)VOID:(
|
||||
print(REPR ABS bits OF nibble)
|
||||
# OD # ))
|
||||
);
|
||||
|
||||
PROC example uuencode nibble stream = VOID: (
|
||||
[]STRING hello world = (
|
||||
"hello, world",
|
||||
"Hello, world!",
|
||||
"Goodbye, cruel world",
|
||||
"I'm leaving you today",
|
||||
"Goodbye, goodbye, goodbye "
|
||||
);
|
||||
|
||||
PROC gen join hello world = (YIELDNIBBLE yield)VOID:
|
||||
gen join(hello world, REPR ABS 8r12, yield); # 8r12 = ASCII new line #
|
||||
|
||||
print((new line, "Encode 8bit CHARs into uue 6bit NIBBLEs:", new line));
|
||||
INT count := 0;
|
||||
# FOR NIBBLE nibble IN # gen resize nibble(6, gen join hello world, # ) DO ( #
|
||||
## (NIBBLE nibble)VOID:(
|
||||
print(encode uue 6bit[ABS bits OF nibble]);
|
||||
count+:=1;
|
||||
IF count MOD 60 = 0 THEN print(newline) FI
|
||||
# OD # ));
|
||||
print(new line); print(new line)
|
||||
);
|
||||
|
||||
PROC example compress 7bit chars = VOID: (
|
||||
STRING example 7bit string = "STRING & ABACUS";
|
||||
|
||||
print(("Convert 7bit ASCII CHARS to a 1bit stream: ",new line,
|
||||
example 7bit string + " => "));
|
||||
|
||||
PROC gen example 7bit string = (YIELDNIBBLE yield)VOID:
|
||||
gen nibble from 7bit chars(example 7bit string,yield);
|
||||
|
||||
# FOR NIBBLE nibble IN # gen resize nibble(1, gen example 7bit string, # ) DO ( #
|
||||
## (NIBBLE nibble)VOID: (
|
||||
print(whole(ABS bits OF nibble,0))
|
||||
# OD # ));
|
||||
print(new line)
|
||||
);
|
||||
|
||||
example uudecode nibble stream;
|
||||
example uuencode nibble stream;
|
||||
example compress 7bit chars
|
||||
20
Task/Bitwise-IO/Ada/bitwise-io-1.ada
Normal file
20
Task/Bitwise-IO/Ada/bitwise-io-1.ada
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
with Ada.Streams; use Ada.Streams;
|
||||
with Ada.Finalization;
|
||||
|
||||
package Bit_Streams is
|
||||
type Bit is range 0..1;
|
||||
type Bit_Array is array (Positive range <>) of Bit;
|
||||
type Bit_Stream (Channel : not null access Root_Stream_Type'Class) is limited private;
|
||||
procedure Read (Stream : in out Bit_Stream; Data : out Bit_Array);
|
||||
procedure Write (Stream : in out Bit_Stream; Data : Bit_Array);
|
||||
private
|
||||
type Bit_Stream (Channel : not null access Root_Stream_Type'Class) is
|
||||
new Ada.Finalization.Limited_Controlled with
|
||||
record
|
||||
Read_Count : Natural := 0;
|
||||
Write_Count : Natural := 0;
|
||||
Input : Stream_Element_Array (1..1);
|
||||
Output : Stream_Element_Array (1..1);
|
||||
end record;
|
||||
overriding procedure Finalize (Stream : in out Bit_Stream);
|
||||
end Bit_Streams;
|
||||
33
Task/Bitwise-IO/Ada/bitwise-io-2.ada
Normal file
33
Task/Bitwise-IO/Ada/bitwise-io-2.ada
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
package body Bit_Streams is
|
||||
procedure Finalize (Stream : in out Bit_Stream) is
|
||||
begin
|
||||
if Stream.Write_Count > 0 then
|
||||
Stream.Output (1) := Stream.Output (1) * 2**(Stream_Element'Size - Stream.Write_Count);
|
||||
Stream.Channel.Write (Stream.Output);
|
||||
end if;
|
||||
end Finalize;
|
||||
procedure Read (Stream : in out Bit_Stream; Data : out Bit_Array) is
|
||||
Last : Stream_Element_Offset;
|
||||
begin
|
||||
for Index in Data'Range loop
|
||||
if Stream.Read_Count = 0 then
|
||||
Stream.Channel.Read (Stream.Input, Last);
|
||||
Stream.Read_Count := Stream_Element'Size;
|
||||
end if;
|
||||
Data (Index) := Bit (Stream.Input (1) / 2**(Stream_Element'Size - 1));
|
||||
Stream.Input (1) := Stream.Input (1) * 2;
|
||||
Stream.Read_Count := Stream.Read_Count - 1;
|
||||
end loop;
|
||||
end Read;
|
||||
procedure Write (Stream : in out Bit_Stream; Data : Bit_Array) is
|
||||
begin
|
||||
for Index in Data'Range loop
|
||||
if Stream.Write_Count = Stream_Element'Size then
|
||||
Stream.Channel.Write (Stream.Output);
|
||||
Stream.Write_Count := 0;
|
||||
end if;
|
||||
Stream.Output (1) := Stream.Output (1) * 2 or Stream_Element (Data (Index));
|
||||
Stream.Write_Count := Stream.Write_Count + 1;
|
||||
end loop;
|
||||
end Write;
|
||||
end Bit_Streams;
|
||||
33
Task/Bitwise-IO/Ada/bitwise-io-3.ada
Normal file
33
Task/Bitwise-IO/Ada/bitwise-io-3.ada
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
|
||||
with Bit_Streams; use Bit_Streams;
|
||||
|
||||
procedure Test_Bit_Streams is
|
||||
File : File_Type;
|
||||
ABACUS : Bit_Array :=
|
||||
( 1,0,0,0,0,0,1, -- A, big endian
|
||||
1,0,0,0,0,1,0, -- B
|
||||
1,0,0,0,0,0,1, -- A
|
||||
1,0,0,0,0,1,1, -- C
|
||||
1,0,1,0,1,0,1, -- U
|
||||
1,0,1,0,0,1,1 -- S
|
||||
);
|
||||
Data : Bit_Array (ABACUS'Range);
|
||||
begin
|
||||
Create (File, Out_File, "abacus.dat");
|
||||
declare
|
||||
Bits : Bit_Stream (Stream (File));
|
||||
begin
|
||||
Write (Bits, ABACUS);
|
||||
end;
|
||||
Close (File);
|
||||
Open (File, In_File, "abacus.dat");
|
||||
declare
|
||||
Bits : Bit_Stream (Stream (File));
|
||||
begin
|
||||
Read (Bits, Data);
|
||||
end;
|
||||
Close (File);
|
||||
if Data /= ABACUS then
|
||||
raise Data_Error;
|
||||
end if;
|
||||
end Test_Bit_Streams;
|
||||
126
Task/Bitwise-IO/AutoHotkey/bitwise-io.ahk
Normal file
126
Task/Bitwise-IO/AutoHotkey/bitwise-io.ahk
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
file = %A_WorkingDir%\z.dat
|
||||
IfExist, %A_WorkingDir%\z.dat
|
||||
FileDelete %file%
|
||||
IfNotEqual ErrorLevel,0, MsgBox Can't delete file "%file%"`nErrorLevel = "%ErrorLevel%"
|
||||
|
||||
res := BinWrite(file,"000102030405060708090a0b0c0d0e0f00")
|
||||
MsgBox ErrorLevel = %ErrorLevel%`nBytes Written = %res%
|
||||
res := BinRead(file,data)
|
||||
MsgBox ErrorLevel = %ErrorLevel%`nBytes Read = %res%`nData = "%data%"
|
||||
|
||||
res := BinWrite(file,"aa00bb",0,2)
|
||||
MsgBox ErrorLevel = %ErrorLevel%`nBytes Written = %res%
|
||||
res := BinRead(file,data)
|
||||
MsgBox ErrorLevel = %ErrorLevel%`nBytes Read = %res%`nData = "%data%"
|
||||
|
||||
res := BinRead(file,data,3,-2)
|
||||
MsgBox ErrorLevel = %ErrorLevel%`nBytes Read = %res%`nData = "%data%"
|
||||
ExitApp
|
||||
|
||||
/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BinWrite ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
| - Open binary file
|
||||
| - (Over)Write n bytes (n = 0: all)
|
||||
| - From offset (offset < 0: counted from end)
|
||||
| - Close file
|
||||
| data -> file[offset + 0..n-1], rest of file unchanged
|
||||
| Return #bytes actually written
|
||||
*/ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
BinWrite(file, data, n=0, offset=0)
|
||||
{
|
||||
; Open file for WRITE (0x40..), OPEN_ALWAYS (4): creates only if it does not exists
|
||||
h := DllCall("CreateFile","str",file,"Uint",0x40000000,"Uint",0,"UInt",0,"UInt",4,"Uint",0,"UInt",0)
|
||||
IfEqual h,-1, SetEnv, ErrorLevel, -1
|
||||
IfNotEqual ErrorLevel,0,Return,0 ; couldn't create the file
|
||||
|
||||
m = 0 ; seek to offset
|
||||
IfLess offset,0, SetEnv,m,2
|
||||
r := DllCall("SetFilePointerEx","Uint",h,"Int64",offset,"UInt *",p,"Int",m)
|
||||
IfEqual r,0, SetEnv, ErrorLevel, -3
|
||||
IfNotEqual ErrorLevel,0, {
|
||||
t = %ErrorLevel% ; save ErrorLevel to be returned
|
||||
DllCall("CloseHandle", "Uint", h)
|
||||
ErrorLevel = %t% ; return seek error
|
||||
Return 0
|
||||
}
|
||||
|
||||
TotalWritten = 0
|
||||
m := Ceil(StrLen(data)/2)
|
||||
If (n <= 0 or n > m)
|
||||
n := m
|
||||
Loop %n%
|
||||
{
|
||||
StringLeft c, data, 2 ; extract next byte
|
||||
StringTrimLeft data, data, 2 ; remove used byte
|
||||
c = 0x%c% ; make it number
|
||||
result := DllCall("WriteFile","UInt",h,"UChar *",c,"UInt",1,"UInt *",Written,"UInt",0)
|
||||
TotalWritten += Written ; count written
|
||||
if (!result or Written < 1 or ErrorLevel)
|
||||
break
|
||||
}
|
||||
|
||||
IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel%
|
||||
|
||||
h := DllCall("CloseHandle", "Uint", h)
|
||||
IfEqual h,-1, SetEnv, ErrorLevel, -2
|
||||
IfNotEqual t,,SetEnv, ErrorLevel, %t%
|
||||
|
||||
Return TotalWritten
|
||||
}
|
||||
|
||||
/* ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BinRead ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
| - Open binary file
|
||||
| - Read n bytes (n = 0: all)
|
||||
| - From offset (offset < 0: counted from end)
|
||||
| - Close file
|
||||
| data (replaced) <- file[offset + 0..n-1]
|
||||
| Return #bytes actually read
|
||||
*/ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
BinRead(file, ByRef data, n=0, offset=0)
|
||||
{
|
||||
h := DllCall("CreateFile","Str",file,"Uint",0x80000000,"Uint",3,"UInt",0,"UInt",3,"Uint",0,"UInt",0)
|
||||
IfEqual h,-1, SetEnv, ErrorLevel, -1
|
||||
IfNotEqual ErrorLevel,0,Return,0 ; couldn't open the file
|
||||
|
||||
m = 0 ; seek to offset
|
||||
IfLess offset,0, SetEnv,m,2
|
||||
r := DllCall("SetFilePointerEx","Uint",h,"Int64",offset,"UInt *",p,"Int",m)
|
||||
IfEqual r,0, SetEnv, ErrorLevel, -3
|
||||
IfNotEqual ErrorLevel,0, {
|
||||
t = %ErrorLevel% ; save ErrorLevel to be returned
|
||||
DllCall("CloseHandle", "Uint", h)
|
||||
ErrorLevel = %t% ; return seek error
|
||||
Return 0
|
||||
}
|
||||
|
||||
TotalRead = 0
|
||||
data =
|
||||
IfEqual n,0, SetEnv n,0xffffffff ; almost infinite
|
||||
|
||||
format = %A_FormatInteger% ; save original integer format
|
||||
SetFormat Integer, Hex ; for converting bytes to hex
|
||||
|
||||
Loop %n%
|
||||
{
|
||||
result := DllCall("ReadFile","UInt",h,"UChar *",c,"UInt",1,"UInt *",Read,"UInt",0)
|
||||
if (!result or Read < 1 or ErrorLevel)
|
||||
break
|
||||
TotalRead += Read ; count read
|
||||
c += 0 ; convert to hex
|
||||
StringTrimLeft c, c, 2 ; remove 0x
|
||||
c = 0%c% ; pad left with 0
|
||||
StringRight c, c, 2 ; always 2 digits
|
||||
data = %data%%c% ; append 2 hex digits
|
||||
}
|
||||
|
||||
IfNotEqual ErrorLevel,0, SetEnv,t,%ErrorLevel%
|
||||
|
||||
h := DllCall("CloseHandle", "Uint", h)
|
||||
IfEqual h,-1, SetEnv, ErrorLevel, -2
|
||||
IfNotEqual t,,SetEnv, ErrorLevel, %t%
|
||||
|
||||
SetFormat Integer, %format% ; restore original format
|
||||
Totalread += 0 ; convert to original format
|
||||
Return TotalRead
|
||||
}
|
||||
43
Task/Bitwise-IO/BBC-BASIC/bitwise-io.basic
Normal file
43
Task/Bitwise-IO/BBC-BASIC/bitwise-io.basic
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
file$ = @tmp$ + "bitwise.tmp"
|
||||
test$ = "Hello, world!"
|
||||
|
||||
REM Write to file, 7 bits per character:
|
||||
file% = OPENOUT(file$)
|
||||
FOR i% = 1 TO LEN(test$)
|
||||
PROCwritebits(file%, ASCMID$(test$,i%), 7)
|
||||
NEXT
|
||||
PROCwritebits(file%, 0, 0)
|
||||
CLOSE #file%
|
||||
|
||||
REM Read from file, 7 bits per character:
|
||||
file% = OPENIN(file$)
|
||||
REPEAT
|
||||
ch% = FNreadbits(file%, 7)
|
||||
VDU ch%
|
||||
UNTIL ch% = 0
|
||||
PRINT
|
||||
CLOSE #file%
|
||||
END
|
||||
|
||||
REM Write n% bits from b% to file f% (n% = 0 to flush):
|
||||
DEF PROCwritebits(f%, b%, n%)
|
||||
PRIVATE a%, c%
|
||||
IF n% = 0 BPUT #f%,a% : a% = 0 : c% = 0
|
||||
WHILE n%
|
||||
IF c% = 8 BPUT #f%,a% : a% = 0 : c% = 0
|
||||
n% -= 1
|
||||
c% += 1
|
||||
IF b% AND 1 << n% THEN a% OR= 1 << (8 - c%)
|
||||
ENDWHILE
|
||||
ENDPROC
|
||||
|
||||
REM Read n% bits from file f%:
|
||||
DEF FNreadbits(f%, n%)
|
||||
PRIVATE a%, c% : LOCAL v%
|
||||
WHILE n%
|
||||
IF c% = 0 a% = BGET#f% : c% = 8
|
||||
n% -= 1
|
||||
c% -= 1
|
||||
v% = v% << 1 OR (a% >> c%) AND 1
|
||||
ENDWHILE
|
||||
= v%
|
||||
145
Task/Bitwise-IO/C-sharp/bitwise-io.cs
Normal file
145
Task/Bitwise-IO/C-sharp/bitwise-io.cs
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
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();
|
||||
}
|
||||
}
|
||||
114
Task/Bitwise-IO/C/bitwise-io.c
Normal file
114
Task/Bitwise-IO/C/bitwise-io.c
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef uint8_t byte;
|
||||
typedef struct {
|
||||
FILE *fp;
|
||||
uint32_t accu;
|
||||
int bits;
|
||||
} bit_io_t, *bit_filter;
|
||||
|
||||
bit_filter b_attach(FILE *f)
|
||||
{
|
||||
bit_filter b = malloc(sizeof(bit_io_t));
|
||||
b->bits = b->accu = 0;
|
||||
b->fp = f;
|
||||
return b;
|
||||
}
|
||||
|
||||
void b_write(byte *buf, size_t n_bits, size_t shift, bit_filter bf)
|
||||
{
|
||||
uint32_t accu = bf->accu;
|
||||
int bits = bf->bits;
|
||||
|
||||
buf += shift / 8;
|
||||
shift %= 8;
|
||||
|
||||
while (n_bits || bits >= 8) {
|
||||
while (bits >= 8) {
|
||||
bits -= 8;
|
||||
fputc(accu >> bits, bf->fp);
|
||||
accu &= (1 << bits) - 1;
|
||||
}
|
||||
while (bits < 8 && n_bits) {
|
||||
accu = (accu << 1) | (((128 >> shift) & *buf) >> (7 - shift));
|
||||
--n_bits;
|
||||
bits++;
|
||||
if (++shift == 8) {
|
||||
shift = 0;
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
}
|
||||
bf->accu = accu;
|
||||
bf->bits = bits;
|
||||
}
|
||||
|
||||
size_t b_read(byte *buf, size_t n_bits, size_t shift, bit_filter bf)
|
||||
{
|
||||
uint32_t accu = bf->accu;
|
||||
int bits = bf->bits;
|
||||
int mask, i = 0;
|
||||
|
||||
buf += shift / 8;
|
||||
shift %= 8;
|
||||
|
||||
while (n_bits) {
|
||||
while (bits && n_bits) {
|
||||
mask = 128 >> shift;
|
||||
if (accu & (1 << (bits - 1))) *buf |= mask;
|
||||
else *buf &= ~mask;
|
||||
|
||||
n_bits--;
|
||||
bits--;
|
||||
|
||||
if (++shift >= 8) {
|
||||
shift = 0;
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
if (!n_bits) break;
|
||||
accu = (accu << 8) | fgetc(bf->fp);
|
||||
bits += 8;
|
||||
}
|
||||
bf->accu = accu;
|
||||
bf->bits = bits;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void b_detach(bit_filter bf)
|
||||
{
|
||||
if (bf->bits) {
|
||||
bf->accu <<= 8 - bf->bits;
|
||||
fputc(bf->accu, bf->fp);
|
||||
}
|
||||
free(bf);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned char s[] = "abcdefghijk";
|
||||
unsigned char s2[11] = {0};
|
||||
int i;
|
||||
|
||||
FILE *f = fopen("test.bin", "wb");
|
||||
bit_filter b = b_attach(f);
|
||||
/* for each byte in s, write 7 bits skipping 1 */
|
||||
for (i = 0; i < 10; i++) b_write(s + i, 7, 1, b);
|
||||
b_detach(b);
|
||||
fclose(f);
|
||||
|
||||
/* read 7 bits and expand to each byte of s2 skipping 1 bit */
|
||||
f = fopen("test.bin", "rb");
|
||||
b = b_attach(f);
|
||||
for (i = 0; i < 10; i++) b_read(s2 + i, 7, 1, b);
|
||||
b_detach(b);
|
||||
fclose(f);
|
||||
|
||||
printf("%10s\n", s2); /* should be the same first 10 bytes as in s */
|
||||
|
||||
return 0;
|
||||
}
|
||||
140
Task/Bitwise-IO/Common-Lisp/bitwise-io-1.lisp
Normal file
140
Task/Bitwise-IO/Common-Lisp/bitwise-io-1.lisp
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
(defpackage :rosetta.bitwise-i/o
|
||||
(:use :common-lisp)
|
||||
(:export :bitwise-i/o-demo))
|
||||
(in-package :rosetta.bitwise-i/o)
|
||||
|
||||
(defun byte->bit-vector (byte byte-bits)
|
||||
"Convert one BYTE into a bit-vector of BYTE-BITS length."
|
||||
(let ((vector (make-array byte-bits :element-type 'bit))
|
||||
(bit-value 1))
|
||||
(declare (optimize (speed 3)))
|
||||
(dotimes (bit-index byte-bits vector)
|
||||
(setf (aref vector bit-index)
|
||||
(if (plusp (logand byte (the (unsigned-byte 8) bit-value)))
|
||||
1 0))
|
||||
(setq bit-value (ash bit-value 1)))))
|
||||
|
||||
(defun bytes->bit-vector (byte-vector byte-bits)
|
||||
"Convert a BYTE-VECTOR into a bit-vector, with each byte taking BYTE-BITS.
|
||||
|
||||
For optimization's sake, I limit the size of the vector to (FLOOR
|
||||
MOST-POSITIVE-FIXNUM BYTE-BITS), which is somewhat ridiculously long,
|
||||
but allows the compiler to trust that indices will fit in a FIXNUM."
|
||||
(reduce (lambda (a b) (concatenate 'bit-vector a b))
|
||||
(map 'list (lambda (byte) (byte->bit-vector byte byte-bits)) byte-vector)))
|
||||
|
||||
(defun ascii-char-p (char)
|
||||
"True if CHAR is an ASCII character"
|
||||
(< (char-code char) #x80))
|
||||
|
||||
(defun assert-ascii-string (string)
|
||||
"`ASSERT' that STRING is an ASCII string."
|
||||
(assert (every #'ascii-char-p string)
|
||||
(string)
|
||||
"STRING must contain only ASCII (7-bit) characters;~%“~a”
|
||||
…contains non-ASCII character~p~:*: ~{~% • ~c ~:*— ~@c ~}"
|
||||
string (coerce (remove-duplicates (remove-if #'ascii-char-p string)
|
||||
:test #'char=)
|
||||
'list)))
|
||||
|
||||
(defun ascii-string->bit-vector (string)
|
||||
"Convert a STRING consisting only of characters in the ASCII \(7-bit)
|
||||
range into a bit-vector of 7 bits per character.
|
||||
|
||||
This assumes \(as is now, in 2017, I believe universally the case) that
|
||||
the local character code system \(as for `CHAR-CODE' and `CODE-CHAR') is
|
||||
Unicode, or at least, a superset of ASCII \(eg: ISO-8859-*)
|
||||
"
|
||||
(check-type string simple-string)
|
||||
(assert-ascii-string string)
|
||||
(bytes->bit-vector (map 'vector #'char-code string) 7))
|
||||
|
||||
(defun pad-bit-vector-to-8 (vector)
|
||||
"Ensure that VECTOR is a multiple of 8 bits in length."
|
||||
(adjust-array vector (* 8 (ceiling (length vector) 8))))
|
||||
|
||||
(defun bit-vector->byte (vector)
|
||||
"Convert VECTOR into a single byte."
|
||||
(declare (optimize (speed 3)))
|
||||
(check-type vector bit-vector)
|
||||
(assert (<= (length vector) 8))
|
||||
(reduce (lambda (x y)
|
||||
(logior (the (unsigned-byte 8)
|
||||
(ash (the (unsigned-byte 8) x) 1))
|
||||
(the bit y)))
|
||||
(reverse vector) :initial-value 0))
|
||||
|
||||
(defun bit-vector->bytes (vector byte-size &key (truncatep nil))
|
||||
"Convert a bit vector VECTOR into a vector of bytes of BYTE-SIZE bits each.
|
||||
|
||||
If TRUNCATEP, then discard any trailing bits."
|
||||
(let* ((out-length (funcall (if truncatep 'floor 'ceiling)
|
||||
(length vector)
|
||||
byte-size))
|
||||
(output (make-array out-length
|
||||
:element-type (list 'unsigned-byte byte-size))))
|
||||
(loop for byte from 0 below out-length
|
||||
for start-bit = 0 then end-bit
|
||||
for end-bit = byte-size then (min (+ byte-size end-bit)
|
||||
(length vector))
|
||||
do (setf (aref output byte)
|
||||
(bit-vector->byte (subseq vector start-bit end-bit))))
|
||||
output))
|
||||
|
||||
(defun ascii-pack-to-8-bit (string)
|
||||
"Pack an ASCII STRING into 8-bit bytes (7→8 bit packing)"
|
||||
(bit-vector->bytes (ascii-string->bit-vector string)
|
||||
8))
|
||||
|
||||
(defun unpack-ascii-from-8-bits (byte-vector)
|
||||
"Convert an 8-bit BYTE-VECTOR into an array of (unpacked) 7-bit bytes."
|
||||
(map 'string #'code-char
|
||||
(bit-vector->bytes
|
||||
(pad-bit-vector-to-8 (bytes->bit-vector byte-vector 8))
|
||||
7
|
||||
:truncatep t)))
|
||||
|
||||
(defun write-7->8-bit-string-to-file (string pathname)
|
||||
"Given a string of 7-bit character STRING, create a new file at PATHNAME
|
||||
with the contents of that string packed into 8-bit bytes."
|
||||
(format *trace-output* "~&Writing string to ~a in packed 7→8 bits…~%“~a”"
|
||||
pathname string)
|
||||
(assert-ascii-string string)
|
||||
(with-open-file (output pathname
|
||||
:direction :output
|
||||
:if-exists :supersede
|
||||
:element-type '(unsigned-byte 8))
|
||||
(write-sequence (ascii-pack-to-8-bit string) output)
|
||||
(finish-output output)
|
||||
(let ((expected-length (ceiling (* (length string) 7) 8)))
|
||||
(assert (= (file-length output) expected-length) ()
|
||||
"The file written was ~:d byte~:p in length, ~
|
||||
but the string supplied should have written ~:d byte~:p."
|
||||
(file-length output) expected-length))))
|
||||
|
||||
(defun read-file-into-byte-array (pathname)
|
||||
"Read a binary file into a byte array"
|
||||
(with-open-file (input pathname
|
||||
:direction :input
|
||||
:if-does-not-exist :error
|
||||
:element-type '(unsigned-byte 8))
|
||||
(let ((buffer (make-array (file-length input)
|
||||
:element-type '(unsigned-byte 8))))
|
||||
(read-sequence buffer input)
|
||||
buffer)))
|
||||
|
||||
(defun read-8->7-bit-string-from-file (pathname)
|
||||
"Read 8-bit packed data from PATHNAME and return it as
|
||||
a 7-bit string."
|
||||
(unpack-ascii-from-8-bits (read-file-into-byte-array pathname)))
|
||||
|
||||
(defun bitwise-i/o-demo (&key (string "Hello, World.")
|
||||
(pathname #p"/tmp/demo.bin"))
|
||||
"Writes STRING to PATHNAME after 7→8 bit packing, then reads it back
|
||||
to validate."
|
||||
(write-7->8-bit-string-to-file string pathname)
|
||||
(let ((read-back (read-8->7-bit-string-from-file pathname)))
|
||||
(assert (equal string read-back) ()
|
||||
"Reading back string got:~%“~a”~%…expected:~%“~a”" read-back string)
|
||||
(format *trace-output* "~&String read back matches:~%“~a”" read-back))
|
||||
(finish-output *trace-output*))
|
||||
26
Task/Bitwise-IO/Common-Lisp/bitwise-io-2.lisp
Normal file
26
Task/Bitwise-IO/Common-Lisp/bitwise-io-2.lisp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
BITWISE-I/O> (bitwise-i/o-demo)
|
||||
|
||||
Writing string to /tmp/demo.bin in packed 7→8 bits…
|
||||
“Hello, World.”
|
||||
String read back matches:
|
||||
“Hello, World.”
|
||||
NIL
|
||||
BITWISE-I/O> (bitwise-i/o-demo :string "It doesn't, however, do UTF-7. So, no ☠ or 🙋")
|
||||
Writing string to /tmp/demo.bin in packed 7→8 bits…
|
||||
“It doesn't, however, do UTF-7. So, no ☠ or 🙋”
|
||||
|
||||
STRING must contain only ASCII (7-bit) characters;
|
||||
“It doesn't, however, do UTF-7. So, no ☠ or 🙋”
|
||||
…contains non-ASCII characters:
|
||||
• ☠ — #\SKULL_AND_CROSSBONES
|
||||
• 🙋 — #\HAPPY_PERSON_RAISING_ONE_HAND
|
||||
[Condition of type SIMPLE-ERROR]
|
||||
|
||||
|
||||
Restarts:
|
||||
0: [CONTINUE] Retry assertion with new value for STRING.
|
||||
1: [RETRY] Retry SLIME REPL evaluation request.
|
||||
2: [*ABORT] Return to SLIME's top level.
|
||||
3: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {10152E8033}>)
|
||||
|
||||
⇒ ABORT
|
||||
133
Task/Bitwise-IO/D/bitwise-io.d
Normal file
133
Task/Bitwise-IO/D/bitwise-io.d
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
import std.stdio: File;
|
||||
import core.stdc.stdio: FILE, fputc, fgetc;
|
||||
import std.string: representation;
|
||||
|
||||
/***********
|
||||
Bitwise I/O, the file must be in binary mode, and its FILE*
|
||||
must be kept open during the usage of BitwiseFile.
|
||||
*/
|
||||
struct BitwiseFile {
|
||||
FILE* fp;
|
||||
uint accu;
|
||||
int bits;
|
||||
|
||||
this(File f)
|
||||
in {
|
||||
assert(f.isOpen);
|
||||
//assert(f.isBinary);
|
||||
} body {
|
||||
this.fp = f.getFP();
|
||||
}
|
||||
|
||||
void write(const(ubyte)[] buf, size_t nBits, size_t shift)
|
||||
nothrow {
|
||||
auto accu = this.accu;
|
||||
auto bits = this.bits;
|
||||
auto bufPtr = buf.ptr;
|
||||
|
||||
bufPtr += shift / 8;
|
||||
shift %= 8;
|
||||
|
||||
while (nBits || bits >= 8) {
|
||||
while (bits >= 8) {
|
||||
bits -= 8;
|
||||
fputc(accu >> bits, this.fp);
|
||||
accu &= (1 << bits) - 1;
|
||||
}
|
||||
while (bits < 8 && nBits) {
|
||||
accu = (accu << 1) |
|
||||
(((128 >> shift) & *bufPtr) >> (7 - shift));
|
||||
nBits--;
|
||||
bits++;
|
||||
shift++;
|
||||
if (shift == 8) {
|
||||
shift = 0;
|
||||
bufPtr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.accu = accu;
|
||||
this.bits = bits;
|
||||
}
|
||||
|
||||
size_t read(ubyte[] buf, size_t nBits, size_t shift) nothrow {
|
||||
auto accu = this.accu;
|
||||
auto bits = this.bits;
|
||||
auto bufPtr = buf.ptr;
|
||||
int i = 0;
|
||||
|
||||
bufPtr += shift / 8;
|
||||
shift %= 8;
|
||||
|
||||
while (nBits) {
|
||||
while (bits && nBits) {
|
||||
immutable mask = 128u >> shift;
|
||||
if (accu & (1 << (bits - 1)))
|
||||
*bufPtr |= mask;
|
||||
else
|
||||
*bufPtr &= ~mask;
|
||||
|
||||
nBits--;
|
||||
bits--;
|
||||
shift++;
|
||||
|
||||
if (shift >= 8) {
|
||||
shift = 0;
|
||||
bufPtr++;
|
||||
}
|
||||
}
|
||||
if (!nBits)
|
||||
break;
|
||||
accu = (accu << 8) | fgetc(this.fp);
|
||||
bits += 8;
|
||||
}
|
||||
|
||||
this.accu = accu;
|
||||
this.bits = bits;
|
||||
return i;
|
||||
}
|
||||
|
||||
void detach() nothrow {
|
||||
if (this.bits) {
|
||||
this.accu <<= 8 - this.bits;
|
||||
fputc(this.accu, this.fp);
|
||||
}
|
||||
this.fp = null;
|
||||
this.accu = 0;
|
||||
this.bits = 0;
|
||||
}
|
||||
|
||||
nothrow ~this() {
|
||||
detach;
|
||||
}
|
||||
}
|
||||
|
||||
void main() { // Demo code.
|
||||
import core.stdc.stdio: fopen, fclose;
|
||||
import std.string: assumeUTF;
|
||||
import std.stdio: writeln;
|
||||
|
||||
immutable data = "abcdefghijk".representation;
|
||||
enum n = data.length;
|
||||
|
||||
// For each ubyte in data, write 7 bits skipping 1.
|
||||
auto fout = File("bitwise_io_test.bin", "wb");
|
||||
auto bf1 = BitwiseFile(fout);
|
||||
foreach (immutable i; 0 .. n)
|
||||
bf1.write(data[i .. $], 7, 1);
|
||||
bf1.detach();
|
||||
fout.close();
|
||||
|
||||
// Read 7 bits and expand to each ubyte of result skipping 1 bit.
|
||||
ubyte[n + 1] result = '\0';
|
||||
auto fin = File("bitwise_io_test.bin", "rb");
|
||||
auto bf2 = BitwiseFile(fin);
|
||||
foreach (immutable i; 0 .. n)
|
||||
bf2.read(result[i .. $], 7, 1);
|
||||
bf2.detach();
|
||||
fin.close();
|
||||
|
||||
// Should be the same chars as 'data'.
|
||||
result.assumeUTF.writeln;
|
||||
}
|
||||
169
Task/Bitwise-IO/Delphi/bitwise-io.delphi
Normal file
169
Task/Bitwise-IO/Delphi/bitwise-io.delphi
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
program Bitwise_IO;
|
||||
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
System.Classes;
|
||||
|
||||
type
|
||||
TBitReader = class
|
||||
private
|
||||
readData: Cardinal;
|
||||
startPosition: Integer;
|
||||
endPosition: Integer;
|
||||
Stream: TStream;
|
||||
procedure Align;
|
||||
function BaseStream: TStream;
|
||||
procedure EnsureData(bitCount: Integer);
|
||||
function GetInBuffer: Integer;
|
||||
public
|
||||
constructor Create(sm: TStream);
|
||||
function Read(bitCount: Integer): Integer;
|
||||
function ReadBit: Boolean;
|
||||
end;
|
||||
|
||||
TBitWriter = class
|
||||
private
|
||||
data: Byte;
|
||||
dataLength: Integer;
|
||||
Stream: TStream;
|
||||
procedure Align;
|
||||
function BaseStream: TStream;
|
||||
function BitsToAligment: Integer;
|
||||
public
|
||||
constructor Create(sm: TStream);
|
||||
procedure Write(value, length: Integer);
|
||||
procedure WriteBit(value: Boolean);
|
||||
end;
|
||||
|
||||
function TBitReader.GetInBuffer: Integer;
|
||||
begin
|
||||
result := endPosition - startPosition;
|
||||
end;
|
||||
|
||||
function TBitReader.BaseStream: TStream;
|
||||
begin
|
||||
result := stream;
|
||||
end;
|
||||
|
||||
constructor TBitReader.Create(sm: TStream);
|
||||
begin
|
||||
Stream := sm;
|
||||
end;
|
||||
|
||||
procedure TBitReader.EnsureData(bitCount: Integer);
|
||||
var
|
||||
readBits: Integer;
|
||||
b: Byte;
|
||||
begin
|
||||
readBits := bitCount - GetInBuffer;
|
||||
while readBits > 0 do
|
||||
begin
|
||||
BaseStream.Read(b, 1);
|
||||
readData := readData or (b shl endPosition);
|
||||
endPosition := endPosition + 8;
|
||||
readBits := readBits - 8;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TBitReader.ReadBit: Boolean;
|
||||
begin
|
||||
Exit(Read(1) > 0);
|
||||
end;
|
||||
|
||||
function TBitReader.Read(bitCount: Integer): Integer;
|
||||
begin
|
||||
EnsureData(bitCount);
|
||||
result := (readData shr startPosition) and ((1 shl bitCount) - 1);
|
||||
startPosition := startPosition + bitCount;
|
||||
if endPosition = startPosition then
|
||||
begin
|
||||
endPosition := ord(startPosition = 0);
|
||||
readData := 0;
|
||||
end
|
||||
else if (startPosition >= 8) then
|
||||
begin
|
||||
readData := readData shr startPosition;
|
||||
endPosition := endPosition - startPosition;
|
||||
startPosition := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TBitReader.Align;
|
||||
begin
|
||||
endPosition := ord(startPosition = 0);
|
||||
readData := 0;
|
||||
end;
|
||||
|
||||
function TBitWriter.BaseStream: TStream;
|
||||
begin
|
||||
Exit(stream);
|
||||
end;
|
||||
|
||||
function TBitWriter.BitsToAligment: Integer;
|
||||
begin
|
||||
Exit((32 - dataLength) mod 8);
|
||||
end;
|
||||
|
||||
constructor TBitWriter.Create(sm: TStream);
|
||||
begin
|
||||
Stream := sm;
|
||||
end;
|
||||
|
||||
procedure TBitWriter.WriteBit(value: Boolean);
|
||||
begin
|
||||
self.Write(ord(value), 1);
|
||||
end;
|
||||
|
||||
procedure TBitWriter.Write(value, length: Integer);
|
||||
var
|
||||
currentData: Cardinal;
|
||||
currentLength: Integer;
|
||||
begin
|
||||
currentData := data or (value shl dataLength);
|
||||
currentLength := dataLength + length;
|
||||
while currentLength >= 8 do
|
||||
begin
|
||||
|
||||
BaseStream.Write(currentData, 1);
|
||||
currentData := currentData shr 8;
|
||||
currentLength := currentLength - 8;
|
||||
end;
|
||||
data := currentData;
|
||||
dataLength := currentLength;
|
||||
end;
|
||||
|
||||
procedure TBitWriter.Align;
|
||||
begin
|
||||
if dataLength > 0 then
|
||||
begin
|
||||
BaseStream.Write(data, 1);
|
||||
data := 0;
|
||||
dataLength := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
ms: TMemoryStream;
|
||||
writer: TBitWriter;
|
||||
reader: TBitReader;
|
||||
|
||||
begin
|
||||
ms := TMemoryStream.create();
|
||||
writer := TBitWriter.create(ms);
|
||||
writer.WriteBit(true);
|
||||
writer.Write(5, 3);
|
||||
writer.Write($0155, 11);
|
||||
writer.Align();
|
||||
ms.Position := 0;
|
||||
reader := TBitReader.create(ms);
|
||||
writeln(reader.ReadBit());
|
||||
writeln(reader.Read(3));
|
||||
writeln(format('0x%.4x', [reader.Read(11)]));
|
||||
reader.Align();
|
||||
ms.Free;
|
||||
writer.Free;
|
||||
reader.Free;
|
||||
Readln;
|
||||
end.
|
||||
79
Task/Bitwise-IO/Ecstasy/bitwise-io.ecstasy
Normal file
79
Task/Bitwise-IO/Ecstasy/bitwise-io.ecstasy
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
53
Task/Bitwise-IO/Erlang/bitwise-io-1.erl
Normal file
53
Task/Bitwise-IO/Erlang/bitwise-io-1.erl
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
-module(bitwise_io).
|
||||
-compile([export_all]).
|
||||
|
||||
%% Erlang allows for easy manipulation of bitstrings. Here I'll
|
||||
%% present a function that can take a message of 8-bit ASCII
|
||||
%% characters and remove the MSB, leaving the same message in 7-bits.
|
||||
|
||||
compress(Message) ->
|
||||
<< <<X:7>> || <<X:8>> <= Message >>.
|
||||
|
||||
%% Here we decompress the message.
|
||||
|
||||
decompress(Message) ->
|
||||
<< <<X:8>> || <<X:7>> <= Message >>.
|
||||
|
||||
%% Now a test to demonstrate that this conversion works:
|
||||
|
||||
test_bitstring_conversion() ->
|
||||
Message = <<"Hello, Rosetta Code!">>,
|
||||
io:format("~p: ~B~n",[Message, bit_size(Message)]),
|
||||
Compressed = compress(Message),
|
||||
io:format("~p: ~B~n",[Compressed, bit_size(Compressed)]),
|
||||
Decompressed = decompress(Compressed),
|
||||
io:format("~p: ~B~n",[Decompressed, bit_size(Decompressed)]),
|
||||
io:format("~p = ~p ? ~p~n",[Message, Decompressed,
|
||||
Message =:= Decompressed]).
|
||||
|
||||
%% Now to show this on file output, we'll write the compressed version
|
||||
%% to a file. Now, erlang's file:write_file expects objects that are
|
||||
%% multiples of 8bits. We'll add padding to allow the writing to
|
||||
%% complete, and then discard the padding when reading the file back
|
||||
%% in.
|
||||
|
||||
test_file_io() ->
|
||||
Message = <<"Hello, Rosetta Code!">>,
|
||||
FileName = "bitwise_io.dat",
|
||||
Compressed = compress(Message),
|
||||
PaddingSize = (8 - (bit_size(Compressed) rem 8)) rem 8,
|
||||
PaddedCompressed = <<Compressed:(bit_size(Compressed))/bitstring,
|
||||
0:PaddingSize>>,
|
||||
file:write_file(FileName,PaddedCompressed),
|
||||
{ok, ReadIn} = file:read_file(FileName),
|
||||
UnpaddedSize = bit_size(ReadIn) - 7,
|
||||
Unpadded =
|
||||
case UnpaddedSize rem 7 =:= 0 of
|
||||
true ->
|
||||
<<T:(UnpaddedSize)/bitstring,_:7>> = ReadIn,
|
||||
T;
|
||||
false ->
|
||||
<< <<X:7>> || <<X:7>> <= ReadIn >>
|
||||
end,
|
||||
Decompressed = decompress(Unpadded),
|
||||
io:format("~p~n",[Decompressed]).
|
||||
8
Task/Bitwise-IO/Erlang/bitwise-io-2.erl
Normal file
8
Task/Bitwise-IO/Erlang/bitwise-io-2.erl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
184> bitwise_io:test_bitstring_conversion().
|
||||
<<"Hello, Rosetta Code!">>: 160
|
||||
<<145,151,102,205,235,16,82,223,207,47,78,152,80,67,223,147,42,1:4>>: 140
|
||||
<<"Hello, Rosetta Code!">>: 160
|
||||
<<"Hello, Rosetta Code!">> = <<"Hello, Rosetta Code!">> ? true
|
||||
ok
|
||||
185> bitwise_io:test_file_io().
|
||||
<<"Hello, Rosetta Code!">>
|
||||
21
Task/Bitwise-IO/Forth/bitwise-io.fth
Normal file
21
Task/Bitwise-IO/Forth/bitwise-io.fth
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
\ writing
|
||||
|
||||
: init-write ( -- b m ) 0 128 ;
|
||||
|
||||
: flush-bits ( b m -- 0 128 ) drop emit init-write ;
|
||||
|
||||
: ?flush-bits ( b m -- b' m' ) dup 128 < if flush-bits then ;
|
||||
|
||||
: write-bit ( b m f -- b' m' )
|
||||
if tuck or swap then
|
||||
2/ dup 0= if flush-bits then ;
|
||||
|
||||
\ reading
|
||||
|
||||
: init-read ( -- b m ) key 128 ;
|
||||
|
||||
: eof? ( b m -- b m f ) dup if false else key? 0= then ;
|
||||
|
||||
: read-bit ( b m -- b' m' f )
|
||||
dup 0= if 2drop init-read then
|
||||
2dup and swap 2/ swap ;
|
||||
203
Task/Bitwise-IO/Go/bitwise-io-1.go
Normal file
203
Task/Bitwise-IO/Go/bitwise-io-1.go
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
// Package bit provides bit-wise IO to an io.Writer and from an io.Reader.
|
||||
package bit
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Order specifies the bit ordering within a byte stream.
|
||||
type Order int
|
||||
|
||||
const (
|
||||
// LSB is for Least Significant Bits first
|
||||
LSB Order = iota
|
||||
// MSB is for Most Significant Bits first
|
||||
MSB
|
||||
)
|
||||
|
||||
// ==== Writing / Encoding ====
|
||||
|
||||
type writer interface {
|
||||
io.ByteWriter
|
||||
Flush() error
|
||||
}
|
||||
|
||||
// Writer implements bit-wise writing to an io.Writer.
|
||||
type Writer struct {
|
||||
w writer
|
||||
order Order
|
||||
write func(uint32, uint) error // writeLSB or writeMSB
|
||||
bits uint32
|
||||
nBits uint
|
||||
err error
|
||||
}
|
||||
|
||||
// writeLSB writes `width` bits of `c` in LSB order.
|
||||
func (w *Writer) writeLSB(c uint32, width uint) error {
|
||||
w.bits |= c << w.nBits
|
||||
w.nBits += width
|
||||
for w.nBits >= 8 {
|
||||
if err := w.w.WriteByte(uint8(w.bits)); err != nil {
|
||||
return err
|
||||
}
|
||||
w.bits >>= 8
|
||||
w.nBits -= 8
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeMSB writes `width` bits of `c` in MSB order.
|
||||
func (w *Writer) writeMSB(c uint32, width uint) error {
|
||||
w.bits |= c << (32 - width - w.nBits)
|
||||
w.nBits += width
|
||||
for w.nBits >= 8 {
|
||||
if err := w.w.WriteByte(uint8(w.bits >> 24)); err != nil {
|
||||
return err
|
||||
}
|
||||
w.bits <<= 8
|
||||
w.nBits -= 8
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteBits writes up to 16 bits of `c` to the underlying writer.
|
||||
// Even for MSB ordering the bits are taken from the lower bits of `c`.
|
||||
// (e.g. WriteBits(0x0f,4) writes four 1 bits).
|
||||
func (w *Writer) WriteBits(c uint16, width uint) error {
|
||||
if w.err == nil {
|
||||
w.err = w.write(uint32(c), width)
|
||||
}
|
||||
return w.err
|
||||
}
|
||||
|
||||
var errClosed = errors.New("bit reader/writer is closed")
|
||||
|
||||
// Close closes the writer, flushing any pending output.
|
||||
// It does not close the underlying writer.
|
||||
func (w *Writer) Close() error {
|
||||
if w.err != nil {
|
||||
if w.err == errClosed {
|
||||
return nil
|
||||
}
|
||||
return w.err
|
||||
}
|
||||
// Write the final bits (zero padded).
|
||||
if w.nBits > 0 {
|
||||
if w.order == MSB {
|
||||
w.bits >>= 24
|
||||
}
|
||||
if w.err = w.w.WriteByte(uint8(w.bits)); w.err != nil {
|
||||
return w.err
|
||||
}
|
||||
}
|
||||
w.err = w.w.Flush()
|
||||
if w.err != nil {
|
||||
return w.err
|
||||
}
|
||||
|
||||
// Make any future calls to Write return errClosed.
|
||||
w.err = errClosed
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewWriter returns a new bit Writer that writes completed bytes to `w`.
|
||||
func NewWriter(w io.Writer, order Order) *Writer {
|
||||
bw := &Writer{order: order}
|
||||
switch order {
|
||||
case LSB:
|
||||
bw.write = bw.writeLSB
|
||||
case MSB:
|
||||
bw.write = bw.writeMSB
|
||||
default:
|
||||
bw.err = errors.New("bit writer: unknown order")
|
||||
return bw
|
||||
}
|
||||
if byteWriter, ok := w.(writer); ok {
|
||||
bw.w = byteWriter
|
||||
} else {
|
||||
bw.w = bufio.NewWriter(w)
|
||||
}
|
||||
return bw
|
||||
}
|
||||
|
||||
// ==== Reading / Decoding ====
|
||||
|
||||
// Reader implements bit-wise reading from an io.Reader.
|
||||
type Reader struct {
|
||||
r io.ByteReader
|
||||
bits uint32
|
||||
nBits uint
|
||||
read func(width uint) (uint16, error) // readLSB or readMSB
|
||||
err error
|
||||
}
|
||||
|
||||
func (r *Reader) readLSB(width uint) (uint16, error) {
|
||||
for r.nBits < width {
|
||||
x, err := r.r.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
r.bits |= uint32(x) << r.nBits
|
||||
r.nBits += 8
|
||||
}
|
||||
bits := uint16(r.bits & (1<<width - 1))
|
||||
r.bits >>= width
|
||||
r.nBits -= width
|
||||
return bits, nil
|
||||
}
|
||||
|
||||
func (r *Reader) readMSB(width uint) (uint16, error) {
|
||||
for r.nBits < width {
|
||||
x, err := r.r.ReadByte()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
r.bits |= uint32(x) << (24 - r.nBits)
|
||||
r.nBits += 8
|
||||
}
|
||||
bits := uint16(r.bits >> (32 - width))
|
||||
r.bits <<= width
|
||||
r.nBits -= width
|
||||
return bits, nil
|
||||
}
|
||||
|
||||
// ReadBits reads up to 16 bits from the underlying reader.
|
||||
func (r *Reader) ReadBits(width uint) (uint16, error) {
|
||||
var bits uint16
|
||||
if r.err == nil {
|
||||
bits, r.err = r.read(width)
|
||||
}
|
||||
return bits, r.err
|
||||
}
|
||||
|
||||
// Close closes the reader.
|
||||
// It does not close the underlying reader.
|
||||
func (r *Reader) Close() error {
|
||||
if r.err != nil && r.err != errClosed {
|
||||
return r.err
|
||||
}
|
||||
r.err = errClosed
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewReader returns a new bit Reader that reads bytes from `r`.
|
||||
func NewReader(r io.Reader, order Order) *Reader {
|
||||
br := new(Reader)
|
||||
switch order {
|
||||
case LSB:
|
||||
br.read = br.readLSB
|
||||
case MSB:
|
||||
br.read = br.readMSB
|
||||
default:
|
||||
br.err = errors.New("bit writer: unknown order")
|
||||
return br
|
||||
}
|
||||
if byteReader, ok := r.(io.ByteReader); ok {
|
||||
br.r = byteReader
|
||||
} else {
|
||||
br.r = bufio.NewReader(r)
|
||||
}
|
||||
return br
|
||||
}
|
||||
65
Task/Bitwise-IO/Go/bitwise-io-2.go
Normal file
65
Task/Bitwise-IO/Go/bitwise-io-2.go
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
package bit
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
)
|
||||
|
||||
func ExampleWriter_WriteBits() {
|
||||
var buf bytes.Buffer
|
||||
bw := NewWriter(&buf, MSB)
|
||||
bw.WriteBits(0x0f, 4) // Writes 1111
|
||||
bw.WriteBits(0x00, 1) // 0
|
||||
bw.WriteBits(0x13, 5) // 1001 1
|
||||
// Close will flush with zero bits, in this case
|
||||
// 0000 00
|
||||
if err := bw.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("%08b", buf.Bytes())
|
||||
// Output:
|
||||
// [11110100 11000000]
|
||||
}
|
||||
|
||||
func Example() {
|
||||
const message = "This is a test."
|
||||
fmt.Printf("%q as bytes: % 02[1]X\n", message, []byte(message))
|
||||
fmt.Printf(" original bits: %08b\n", []byte(message))
|
||||
|
||||
// Re-write in 7 bit chunks to buf:
|
||||
var buf bytes.Buffer
|
||||
bw := NewWriter(&buf, MSB)
|
||||
for _, r := range message {
|
||||
bw.WriteBits(uint16(r), 7) // nolint: errcheck
|
||||
}
|
||||
if err := bw.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("Written bitstream: %08b\n", buf.Bytes())
|
||||
fmt.Printf("Written bytes: % 02X\n", buf.Bytes())
|
||||
|
||||
// Read back in 7 bit chunks:
|
||||
br := NewReader(&buf, MSB)
|
||||
var result []byte
|
||||
for {
|
||||
v, err := br.ReadBits(7)
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
log.Fatal(err)
|
||||
}
|
||||
break
|
||||
}
|
||||
if v != 0 {
|
||||
result = append(result, byte(v))
|
||||
}
|
||||
}
|
||||
fmt.Printf("Read back as \"%s\"\n", result)
|
||||
// Output:
|
||||
// "This is a test." as bytes: 54 68 69 73 20 69 73 20 61 20 74 65 73 74 2E
|
||||
// original bits: [01010100 01101000 01101001 01110011 00100000 01101001 01110011 00100000 01100001 00100000 01110100 01100101 01110011 01110100 00101110]
|
||||
// Written bitstream: [10101001 10100011 01001111 00110100 00011010 01111001 10100000 11000010 10000011 10100110 01011110 01111101 00010111 00000000]
|
||||
// Written bytes: A9 A3 4F 34 1A 79 A0 C2 83 A6 5E 7D 17 00
|
||||
// Read back as "This is a test."
|
||||
}
|
||||
30
Task/Bitwise-IO/Haskell/bitwise-io.hs
Normal file
30
Task/Bitwise-IO/Haskell/bitwise-io.hs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import Data.List
|
||||
import Data.Char
|
||||
import Control.Monad
|
||||
import Control.Arrow
|
||||
import System.Environment
|
||||
|
||||
int2bin :: Int -> [Int]
|
||||
int2bin = unfoldr(\x -> if x==0 then Nothing
|
||||
else Just (uncurry(flip(,)) (divMod x 2)))
|
||||
|
||||
bin2int :: [Int] -> Int
|
||||
bin2int = foldr ((.(2 *)).(+)) 0
|
||||
|
||||
bitReader = map (chr.bin2int). takeWhile(not.null). unfoldr(Just. splitAt 7)
|
||||
. (take =<< (7 *) . (`div` 7) . length)
|
||||
|
||||
bitWriter xs = tt ++ z00 where
|
||||
tt = concatMap (take 7.(++repeat 0).int2bin.ord) xs
|
||||
z00 = replicate (length xs `mod` 8) 0
|
||||
|
||||
main = do
|
||||
(xs:_) <- getArgs
|
||||
let bits = bitWriter xs
|
||||
|
||||
putStrLn "Text to compress:"
|
||||
putStrLn $ '\t' : xs
|
||||
putStrLn $ "Uncompressed text length is " ++ show (length xs)
|
||||
putStrLn $ "Compressed text has " ++ show (length bits `div` 8) ++ " bytes."
|
||||
putStrLn "Read and decompress:"
|
||||
putStrLn $ '\t' : bitReader bits
|
||||
2
Task/Bitwise-IO/J/bitwise-io-1.j
Normal file
2
Task/Bitwise-IO/J/bitwise-io-1.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
bitReader =: a. {~ _7 #.\ ({.~ <.&.(%&7)@#)
|
||||
bitWriter =: , @ ((7$2) & #: @ (a.&i.)), 0 $~ 8 | #
|
||||
4
Task/Bitwise-IO/J/bitwise-io-2.j
Normal file
4
Task/Bitwise-IO/J/bitwise-io-2.j
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
text=: 'This text is used to illustrate the Rosetta Code task about ''bit oriented IO''.'
|
||||
|
||||
bitReader bitWriter text
|
||||
This text is used to illustrate the Rosetta Code task about 'bit oriented IO'.
|
||||
2
Task/Bitwise-IO/J/bitwise-io-3.j
Normal file
2
Task/Bitwise-IO/J/bitwise-io-3.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# text
|
||||
78
|
||||
2
Task/Bitwise-IO/J/bitwise-io-4.j
Normal file
2
Task/Bitwise-IO/J/bitwise-io-4.j
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
%&8 # bitWriter text
|
||||
69
|
||||
48
Task/Bitwise-IO/Julia/bitwise-io.julia
Normal file
48
Task/Bitwise-IO/Julia/bitwise-io.julia
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
function compress7(inio, outio)
|
||||
nextwritebyte = read(inio, UInt8) & 0x7f
|
||||
filled = 7
|
||||
while !eof(inio)
|
||||
inbyte = read(inio, UInt8)
|
||||
write(outio, UInt8(nextwritebyte | inbyte << filled))
|
||||
nextwritebyte = inbyte >> (8 - filled)
|
||||
filled = (filled + 7) % 8
|
||||
if filled == 0
|
||||
if eof(inio)
|
||||
break
|
||||
end
|
||||
nextwritebyte = read(inio, UInt8) & 0x7f
|
||||
filled = 7
|
||||
end
|
||||
end
|
||||
if filled != 0
|
||||
write(outio, UInt8(nextwritebyte))
|
||||
end
|
||||
end
|
||||
|
||||
function expand7(inio, outio)
|
||||
newbyte = read(inio, UInt8)
|
||||
write(outio, UInt8(newbyte & 0x7f))
|
||||
residualbyte::UInt8 = newbyte >> 7
|
||||
filled = 1
|
||||
while !eof(inio)
|
||||
inbyte = read(inio, UInt8)
|
||||
write(outio, UInt8((residualbyte | inbyte << filled) & 0x7f))
|
||||
residualbyte = inbyte >> (7 - filled)
|
||||
filled = (filled + 1) % 7
|
||||
if filled == 0
|
||||
write(outio, UInt8(residualbyte & 0x7f))
|
||||
residualbyte = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
str = b"These bit oriented I/O functions can be used to implement compressors and decompressors."
|
||||
ins = IOBuffer(str)
|
||||
outs = IOBuffer()
|
||||
newouts = IOBuffer()
|
||||
compress7(ins, outs)
|
||||
seek(outs,0)
|
||||
expand7(outs, newouts)
|
||||
println("Initial string of length $(length(str)): ", String(ins.data))
|
||||
println("Compressed to length $(length(outs.data)) on line below:\n", String(outs.data))
|
||||
println("Decompressed string: ", String(newouts.data))
|
||||
84
Task/Bitwise-IO/Kotlin/bitwise-io.kotlin
Normal file
84
Task/Bitwise-IO/Kotlin/bitwise-io.kotlin
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
// version 1.2.31
|
||||
|
||||
import java.io.File
|
||||
|
||||
class BitFilter(val f: File, var accu: Int = 0, var bits: Int = 0) {
|
||||
|
||||
private val bw = f.bufferedWriter()
|
||||
private val br = f.bufferedReader()
|
||||
|
||||
fun write(buf: ByteArray, start: Int, _nBits: Int, _shift: Int) {
|
||||
var nBits = _nBits
|
||||
var index = start + _shift / 8
|
||||
var shift = _shift % 8
|
||||
|
||||
while (nBits != 0 || bits >= 8) {
|
||||
while (bits >= 8) {
|
||||
bits -= 8
|
||||
bw.write(accu ushr bits)
|
||||
accu = accu and ((1 shl bits) - 1)
|
||||
}
|
||||
while (bits < 8 && nBits != 0) {
|
||||
val b = buf[index].toInt()
|
||||
accu = (accu shl 1) or (((128 ushr shift) and b) ushr (7 - shift))
|
||||
nBits--
|
||||
bits++
|
||||
if (++shift == 8) { shift = 0; index++ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun read(buf: ByteArray, start: Int, _nBits: Int, _shift: Int) {
|
||||
var nBits = _nBits
|
||||
var index = start + _shift / 8
|
||||
var shift = _shift % 8
|
||||
|
||||
while (nBits != 0) {
|
||||
while (bits != 0 && nBits != 0) {
|
||||
val mask = 128 ushr shift
|
||||
if ((accu and (1 shl (bits - 1))) != 0)
|
||||
buf[index] = (buf[index].toInt() or mask).toByte()
|
||||
else
|
||||
buf[index] = (buf[index].toInt() and mask.inv()).toByte()
|
||||
nBits--
|
||||
bits--
|
||||
if (++shift >= 8) { shift = 0; index++ }
|
||||
}
|
||||
if (nBits == 0) break
|
||||
accu = (accu shl 8) or br.read()
|
||||
bits += 8
|
||||
}
|
||||
}
|
||||
|
||||
fun closeWriter() {
|
||||
if (bits != 0) {
|
||||
accu = (accu shl (8 - bits))
|
||||
bw.write(accu)
|
||||
}
|
||||
bw.close()
|
||||
accu = 0
|
||||
bits = 0
|
||||
}
|
||||
|
||||
fun closeReader() {
|
||||
br.close()
|
||||
accu = 0
|
||||
bits = 0
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val s = "abcdefghijk".toByteArray(Charsets.UTF_8)
|
||||
val f = File("test.bin")
|
||||
val bf = BitFilter(f)
|
||||
|
||||
/* for each byte in s, write 7 bits skipping 1 */
|
||||
for (i in 0 until s.size) bf.write(s, i, 7, 1)
|
||||
bf.closeWriter()
|
||||
|
||||
/* read 7 bits and expand to each byte of s2 skipping 1 bit */
|
||||
val s2 = ByteArray(s.size)
|
||||
for (i in 0 until s2.size) bf.read(s2, i, 7, 1)
|
||||
bf.closeReader()
|
||||
println(String(s2, Charsets.UTF_8))
|
||||
}
|
||||
63
Task/Bitwise-IO/Lingo/bitwise-io-1.lingo
Normal file
63
Task/Bitwise-IO/Lingo/bitwise-io-1.lingo
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
-- parent script "BitArray"
|
||||
|
||||
property ancestor
|
||||
property bitSize
|
||||
property _pow2
|
||||
|
||||
----------------------------------------
|
||||
-- @constructor
|
||||
-- @param {integer} [bSize=0]
|
||||
----------------------------------------
|
||||
on new (me, bSize)
|
||||
if voidP(bitSize) then bitSize=0
|
||||
me.bitSize = bSize
|
||||
byteSize = bitSize/8 + (bitSize mod 8>0)
|
||||
me._pow2 = [128,64,32,16,8,4,2,1] -- pow2 lookup list
|
||||
me.ancestor = ByteArray(byteSize)
|
||||
return me
|
||||
end
|
||||
|
||||
----------------------------------------
|
||||
-- Sets bit at position <bitPos> to <bitValue>.
|
||||
-- @param {integer} bitPos - starts at 1, as ByteArray's native byte access functions
|
||||
-- @param {boolean} bitValue
|
||||
----------------------------------------
|
||||
on setBit (me, bitPos, bitValue)
|
||||
bytePos = (bitPos-1)/8 + 1
|
||||
bitPos = (bitPos-1) mod 8 + 1
|
||||
if bitValue then
|
||||
me[bytePos] = bitOr(me[bytePos], me._pow2[bitPos])
|
||||
else
|
||||
me[bytePos] = bitAnd(me[bytePos], bitNot(me._pow2[bitPos]))
|
||||
end if
|
||||
end
|
||||
|
||||
----------------------------------------
|
||||
-- Gets bit value at position <bitPos>.
|
||||
-- @param {integer} bitPos - starts at 1, as ByteArray's native byte access functions
|
||||
-- @return {boolean} bitValue
|
||||
----------------------------------------
|
||||
on getBit (me, bitPos)
|
||||
bytePos = (bitPos-1)/8 + 1
|
||||
bitPos = (bitPos-1) mod 8 + 1
|
||||
return bitAnd(me[bytePos], me._pow2[bitPos])<>0
|
||||
end
|
||||
|
||||
----------------------------------------
|
||||
-- Returns all bits as string. To be in accordance with ByteArray's native toHexString(),
|
||||
-- returned string is separated with SPACE (e.g. "0 1 1 0...")
|
||||
-- @param {integer} [bitSizeOnly=FALSE] - if TRUE, only <bitSize> bits without byte-padding
|
||||
-- @return {string}
|
||||
----------------------------------------
|
||||
on toBinString (me, bitSizeOnly)
|
||||
res = ""
|
||||
repeat with i = 1 to me.length
|
||||
byte = me[i]
|
||||
repeat with j = 1 to 8
|
||||
put (bitAnd(byte, me._pow2[j])<>0)&" " after res
|
||||
if bitSizeOnly and (i-1)*8+j=me.bitSize then exit repeat
|
||||
end repeat
|
||||
end repeat
|
||||
delete the last char of res
|
||||
return res
|
||||
end
|
||||
37
Task/Bitwise-IO/Lingo/bitwise-io-2.lingo
Normal file
37
Task/Bitwise-IO/Lingo/bitwise-io-2.lingo
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
----------------------------------------
|
||||
-- @param {string} str - ASCII string
|
||||
-- @return {instance} BitArray
|
||||
----------------------------------------
|
||||
on crunchASCII (str)
|
||||
ba = script("BitArray").new(str.length * 7)
|
||||
pow2 = [64,32,16,8,4,2,1]
|
||||
pos = 1
|
||||
repeat with i = 1 to str.length
|
||||
n = chartonum(str.char[i])
|
||||
repeat with j = 1 to 7
|
||||
ba.setBit(pos, bitAnd(n, pow2[j])<>0)
|
||||
pos = pos+1
|
||||
end repeat
|
||||
end repeat
|
||||
return ba
|
||||
end
|
||||
|
||||
----------------------------------------
|
||||
-- @param {instance} bitArray
|
||||
-- @return {string} ASCII string
|
||||
----------------------------------------
|
||||
on decrunchASCII (bitArray)
|
||||
str = ""
|
||||
pow2 = [64,32,16,8,4,2,1]
|
||||
pos = 1
|
||||
cnt = bitArray.bitSize/7
|
||||
repeat with i = 1 to cnt
|
||||
n = 0
|
||||
repeat with j = 1 to 7
|
||||
n = n + bitArray.getBit(pos)*pow2[j]
|
||||
pos = pos+1
|
||||
end repeat
|
||||
put numtochar(n) after str
|
||||
end repeat
|
||||
return str
|
||||
end
|
||||
11
Task/Bitwise-IO/Lingo/bitwise-io-3.lingo
Normal file
11
Task/Bitwise-IO/Lingo/bitwise-io-3.lingo
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
str = "ABC"
|
||||
ba = crunchASCII(str)
|
||||
|
||||
put ba.toBinString()
|
||||
-- "1 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0"
|
||||
|
||||
put ba.toBinString(TRUE)
|
||||
-- "1 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 0 0 1 1"
|
||||
|
||||
put decrunchASCII(ba)
|
||||
-- "ABC"
|
||||
70
Task/Bitwise-IO/Lua/bitwise-io-1.lua
Normal file
70
Task/Bitwise-IO/Lua/bitwise-io-1.lua
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
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
|
||||
37
Task/Bitwise-IO/Lua/bitwise-io-2.lua
Normal file
37
Task/Bitwise-IO/Lua/bitwise-io-2.lua
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
-- 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))
|
||||
96
Task/Bitwise-IO/Nim/bitwise-io.nim
Normal file
96
Task/Bitwise-IO/Nim/bitwise-io.nim
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
type
|
||||
BitWriter * = tuple
|
||||
file: File
|
||||
bits: uint8
|
||||
nRemain: int
|
||||
|
||||
BitReader * = tuple
|
||||
file: File
|
||||
bits: uint8
|
||||
nRemain: int
|
||||
nRead: int
|
||||
|
||||
proc newBitWriter * (file: File) : ref BitWriter =
|
||||
result = new BitWriter
|
||||
result.file = file
|
||||
result.bits = 0
|
||||
result.nRemain = 8
|
||||
|
||||
proc flushBits (stream : ref BitWriter) =
|
||||
discard stream.file.writeBuffer(stream.bits.addr, 1)
|
||||
stream.nRemain = 8
|
||||
stream.bits = 0
|
||||
|
||||
proc write * (stream: ref BitWriter, bits: uint8, nBits: int) =
|
||||
assert(nBits <= 8)
|
||||
|
||||
for ii in countdown((nBits - 1), 0) :
|
||||
stream.bits = (stream.bits shl 1) or ((bits shr ii) and 1)
|
||||
stream.nRemain.dec(1)
|
||||
if stream.nRemain == 0:
|
||||
stream.flushBits
|
||||
|
||||
proc flush * (stream: ref BitWriter) =
|
||||
if stream.nRemain < 8:
|
||||
stream.bits = stream.bits shl stream.nRemain
|
||||
stream.flushBits
|
||||
|
||||
proc newBitReader * (file: File) : ref BitReader =
|
||||
result = new BitReader
|
||||
result.file = file
|
||||
result.bits = 0
|
||||
result.nRemain = 0
|
||||
result.nRead = 0
|
||||
|
||||
proc read * (stream: ref BitReader, nBits: int) : uint8 =
|
||||
assert(nBits <= 8)
|
||||
|
||||
result = 0
|
||||
for ii in 0 ..< nBits :
|
||||
if stream.nRemain == 0:
|
||||
stream.nRead = stream.file.readBuffer(stream.bits.addr, 1)
|
||||
if stream.nRead == 0:
|
||||
break
|
||||
stream.nRemain = 8
|
||||
|
||||
result = (result shl 1) or ((stream.bits shr 7) and 1)
|
||||
|
||||
stream.bits = stream.bits shl 1
|
||||
stream.nRemain.dec(1)
|
||||
|
||||
|
||||
when isMainModule:
|
||||
var
|
||||
file: File
|
||||
writer: ref BitWriter
|
||||
reader: ref BitReader
|
||||
|
||||
file = open("testfile.dat", fmWrite)
|
||||
writer = newBitWriter(file)
|
||||
|
||||
for ii in 0 .. 255:
|
||||
writer.write(ii.uint8, 7)
|
||||
|
||||
writer.flush
|
||||
file.close
|
||||
|
||||
var dataCtr = 0
|
||||
|
||||
file = open("testfile.dat", fmRead)
|
||||
reader = newBitReader(file)
|
||||
|
||||
while true:
|
||||
let aByte = reader.read(7)
|
||||
|
||||
if reader.nRead == 0:
|
||||
break
|
||||
|
||||
assert((dataCtr and 0x7f).uint8 == aByte)
|
||||
|
||||
inc dataCtr
|
||||
|
||||
assert(dataCtr == 256)
|
||||
|
||||
file.close
|
||||
|
||||
echo "OK"
|
||||
7
Task/Bitwise-IO/OCaml/bitwise-io-1.ocaml
Normal file
7
Task/Bitwise-IO/OCaml/bitwise-io-1.ocaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
let write_7bit_string ~filename ~str =
|
||||
let oc = open_out filename in
|
||||
let ob = IO.output_bits(IO.output_channel oc) in
|
||||
String.iter (fun c -> IO.write_bits ob 7 (int_of_char c)) str;
|
||||
IO.flush_bits ob;
|
||||
close_out oc;
|
||||
;;
|
||||
10
Task/Bitwise-IO/OCaml/bitwise-io-2.ocaml
Normal file
10
Task/Bitwise-IO/OCaml/bitwise-io-2.ocaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
let read_7bit_string ~filename =
|
||||
let ic = open_in filename in
|
||||
let ib = IO.input_bits(IO.input_channel ic) in
|
||||
let buf = Buffer.create 2048 in
|
||||
try while true do
|
||||
let c = IO.read_bits ib 7 in
|
||||
Buffer.add_char buf (char_of_int c);
|
||||
done; ""
|
||||
with IO.No_more_input ->
|
||||
(Buffer.contents buf)
|
||||
11
Task/Bitwise-IO/PL-I/bitwise-io.pli
Normal file
11
Task/Bitwise-IO/PL-I/bitwise-io.pli
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
declare onebit bit(1) aligned, bs bit (1000) varying aligned;
|
||||
on endfile (sysin) go to ending;
|
||||
bs = ''b;
|
||||
do forever;
|
||||
get edit (onebit) (F(1));
|
||||
bs = bs || onebit;
|
||||
end;
|
||||
ending:
|
||||
bs = bs || copy('0'b, mod(length(bs), 8) );
|
||||
/* pad length to a multiple of 8 */
|
||||
put edit (bs) (b);
|
||||
42
Task/Bitwise-IO/Perl/bitwise-io-1.pl
Normal file
42
Task/Bitwise-IO/Perl/bitwise-io-1.pl
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
use strict;
|
||||
|
||||
# $buffer = write_bits(*STDOUT, $buffer, $number, $bits)
|
||||
sub write_bits :prototype( $$$$ )
|
||||
{
|
||||
my ($out, $l, $num, $q) = @_;
|
||||
$l .= substr(unpack("B*", pack("N", $num)),
|
||||
-$q);
|
||||
if ( (length($l) > 8) ) {
|
||||
my $left = substr($l, 8);
|
||||
print $out pack("B8", $l);
|
||||
$l = $left;
|
||||
}
|
||||
return $l;
|
||||
}
|
||||
|
||||
# flush_bits(*STDOUT, $buffer)
|
||||
sub flush_bits :prototype( $$ )
|
||||
{
|
||||
my ($out, $b) = @_;
|
||||
print $out pack("B*", $b);
|
||||
}
|
||||
|
||||
# ($val, $buf) = read_bits(*STDIN, $buf, $n)
|
||||
sub read_bits :prototype( $$$ )
|
||||
{
|
||||
my ( $in, $b, $n ) = @_;
|
||||
# we put a limit in the number of bits we can read
|
||||
# with one shot; this should mirror the limit of the max
|
||||
# integer value perl can hold
|
||||
if ( $n > 32 ) { return 0; }
|
||||
while ( length($b) < $n ) {
|
||||
my $v;
|
||||
my $red = read($in, $v, 1);
|
||||
if ( $red < 1 ) { return ( 0, -1 ); }
|
||||
$b .= substr(unpack("B*", $v), -8);
|
||||
}
|
||||
my $bits = "0" x ( 32-$n ) . substr($b, 0, $n);
|
||||
my $val = unpack("N", pack("B32", $bits));
|
||||
$b = substr($b, $n);
|
||||
return ($val, $b);
|
||||
}
|
||||
6
Task/Bitwise-IO/Perl/bitwise-io-2.pl
Normal file
6
Task/Bitwise-IO/Perl/bitwise-io-2.pl
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
my $buf = "";
|
||||
my $c;
|
||||
while( read(*STDIN, $c, 1) > 0 ) {
|
||||
$buf = write_bits(*STDOUT, $buf, unpack("C1", $c), 7);
|
||||
}
|
||||
flush_bits(*STDOUT, $buf);
|
||||
7
Task/Bitwise-IO/Perl/bitwise-io-3.pl
Normal file
7
Task/Bitwise-IO/Perl/bitwise-io-3.pl
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
my $buf = "";
|
||||
my $v;
|
||||
while(1) {
|
||||
( $v, $buf ) = read_bits(*STDIN, $buf, 7);
|
||||
last if ($buf < 0);
|
||||
print pack("C1", $v);
|
||||
}
|
||||
106
Task/Bitwise-IO/Phix/bitwise-io.phix
Normal file
106
Task/Bitwise-IO/Phix/bitwise-io.phix
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
(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 = "This is a test"
|
||||
--constant test = "abcdefghijk"
|
||||
--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>
|
||||
<!--
|
||||
22
Task/Bitwise-IO/PicoLisp/bitwise-io-1.l
Normal file
22
Task/Bitwise-IO/PicoLisp/bitwise-io-1.l
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
(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) ) ) ) )
|
||||
11
Task/Bitwise-IO/PicoLisp/bitwise-io-2.l
Normal file
11
Task/Bitwise-IO/PicoLisp/bitwise-io-2.l
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
(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))))
|
||||
120
Task/Bitwise-IO/PureBasic/bitwise-io.basic
Normal file
120
Task/Bitwise-IO/PureBasic/bitwise-io.basic
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
Structure fileDataBits
|
||||
bitsToWrite.i
|
||||
bitsToRead.i
|
||||
outputByte.i
|
||||
inputByte.i
|
||||
EndStructure
|
||||
#BitsPerByte = SizeOf(Byte) * 8
|
||||
#BitsPerInteger = SizeOf(Integer) * 8
|
||||
|
||||
Global Dim fileBitMask(8)
|
||||
Define i, x
|
||||
For i = 0 To 8
|
||||
fileBitMask(i) = x
|
||||
x = (x << 1) + 1
|
||||
Next
|
||||
|
||||
Global NewMap fileDataBits.fileDataBits()
|
||||
Procedure flushBits(fileID)
|
||||
If FindMapElement(fileDataBits(), Str(fileID))
|
||||
If fileDataBits()\bitsToWrite > 0
|
||||
WriteByte(fileID, fileDataBits()\outputByte << (#BitsPerByte - fileDataBits()\bitsToWrite))
|
||||
fileDataBits()\bitsToWrite = 0
|
||||
fileDataBits()\outputByte = 0
|
||||
EndIf
|
||||
DeleteMapElement(fileDataBits())
|
||||
EndIf
|
||||
EndProcedure
|
||||
|
||||
Procedure writeBits(fileID, Value.i, bitCount)
|
||||
Protected *fileData.fileDataBits = FindMapElement(fileDataBits(), Str(fileID))
|
||||
If Not *fileData
|
||||
*fileData = AddMapElement(fileDataBits(), Str(fileID))
|
||||
If Not *fileData: End: EndIf ;simple error check for lack of memory
|
||||
EndIf
|
||||
|
||||
Value << (#BitsPerInteger - bitCount) ;shift value so it's first bit (HSB) is in the highest position
|
||||
While bitCount > 0
|
||||
If bitCount > #BitsPerByte - *fileData\bitsToWrite
|
||||
bitGroupSize = #BitsPerByte - *fileData\bitsToWrite
|
||||
Else
|
||||
bitGroupSize = bitCount
|
||||
EndIf
|
||||
|
||||
*fileData\outputByte << bitGroupSize
|
||||
*fileData\outputByte + (Value >> (#BitsPerInteger - bitGroupSize)) & fileBitMask(bitGroupSize)
|
||||
Value << bitGroupSize
|
||||
*fileData\bitsToWrite + bitGroupSize
|
||||
If *fileData\bitsToWrite = #BitsPerByte
|
||||
WriteByte(fileID, *fileData\outputByte)
|
||||
*fileData\bitsToWrite = 0
|
||||
*fileData\outputByte = 0
|
||||
EndIf
|
||||
bitCount - bitGroupSize
|
||||
Wend
|
||||
EndProcedure
|
||||
|
||||
Procedure.i readBits(fileID, bitCount)
|
||||
Protected *fileData.fileDataBits = FindMapElement(fileDataBits(), Str(fileID))
|
||||
If Not *fileData
|
||||
*fileData = AddMapElement(fileDataBits(), Str(fileID))
|
||||
If Not *fileData: End: EndIf ;simple error check for lack of memory
|
||||
EndIf
|
||||
|
||||
Protected Value.i, bitGroupSize
|
||||
While bitCount > 0
|
||||
If *fileData\bitsToRead = 0
|
||||
If Not Eof(fileID)
|
||||
*fileData\inputByte = ReadByte(fileID)
|
||||
*fileData\bitsToRead = #BitsPerByte
|
||||
Else
|
||||
flushBits(fileID)
|
||||
Break ;simple error check aborts if nothing left to read
|
||||
EndIf
|
||||
EndIf
|
||||
|
||||
If bitCount > *fileData\bitsToRead
|
||||
bitGroupSize = *fileData\bitsToRead
|
||||
Else
|
||||
bitGroupSize = bitCount
|
||||
EndIf
|
||||
Value << bitGroupSize
|
||||
Value + (*fileData\inputByte >> (#BitsPerByte - bitGroupSize)) & fileBitMask(bitGroupSize) ;shift last bit being read in byte to the lowest position
|
||||
*fileData\inputByte << bitGroupSize
|
||||
*fileData\bitsToRead - bitGroupSize
|
||||
bitCount - bitGroupSize
|
||||
Wend
|
||||
ProcedureReturn Value
|
||||
EndProcedure
|
||||
|
||||
;test
|
||||
Define testWriteString.s, testReadString.s, fileNum, result.s
|
||||
testWriteString = "This is an ascii string that will be crunched, written, read and expanded."
|
||||
fileNum = CreateFile(#PB_Any, "BitIO_Test.dat")
|
||||
If fileNum
|
||||
For i = 1 To Len(testWriteString)
|
||||
writeBits(fileNum, Asc(Mid(testWriteString, i, 1)), 7)
|
||||
Next
|
||||
flushBits(fileNum)
|
||||
CloseFile(fileNum)
|
||||
EndIf
|
||||
|
||||
fileNum = ReadFile(#PB_Any, "BitIO_Test.dat")
|
||||
If fileNum
|
||||
For i = 1 To Len(testWriteString)
|
||||
testReadString + Chr(readBits(fileNum, 7))
|
||||
Next
|
||||
flushBits(fileNum)
|
||||
CloseFile(fileNum)
|
||||
EndIf
|
||||
|
||||
result = "Original ascii string is " + Str(Len(testWriteString)) + " bytes." + #LF$
|
||||
result + "Filesize written is " + Str(FileSize("test.xxx")) + " bytes." + #LF$
|
||||
If testReadString = testWriteString
|
||||
result + "The expanded string is the same as the original." + #LF$
|
||||
Else
|
||||
result + "The expanded string is not the same as the original." + #LF$
|
||||
EndIf
|
||||
result + "Expanded string = '" + testReadString + "'"
|
||||
|
||||
MessageRequester("Results", result)
|
||||
89
Task/Bitwise-IO/Python/bitwise-io-1.py
Normal file
89
Task/Bitwise-IO/Python/bitwise-io-1.py
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
class BitWriter(object):
|
||||
def __init__(self, f):
|
||||
self.accumulator = 0
|
||||
self.bcount = 0
|
||||
self.out = f
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.flush()
|
||||
|
||||
def __del__(self):
|
||||
try:
|
||||
self.flush()
|
||||
except ValueError: # I/O operation on closed file.
|
||||
pass
|
||||
|
||||
def _writebit(self, bit):
|
||||
if self.bcount == 8:
|
||||
self.flush()
|
||||
if bit > 0:
|
||||
self.accumulator |= 1 << 7-self.bcount
|
||||
self.bcount += 1
|
||||
|
||||
def writebits(self, bits, n):
|
||||
while n > 0:
|
||||
self._writebit(bits & 1 << n-1)
|
||||
n -= 1
|
||||
|
||||
def flush(self):
|
||||
self.out.write(bytearray([self.accumulator]))
|
||||
self.accumulator = 0
|
||||
self.bcount = 0
|
||||
|
||||
|
||||
class BitReader(object):
|
||||
def __init__(self, f):
|
||||
self.input = f
|
||||
self.accumulator = 0
|
||||
self.bcount = 0
|
||||
self.read = 0
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
pass
|
||||
|
||||
def _readbit(self):
|
||||
if not self.bcount:
|
||||
a = self.input.read(1)
|
||||
if a:
|
||||
self.accumulator = ord(a)
|
||||
self.bcount = 8
|
||||
self.read = len(a)
|
||||
rv = (self.accumulator & (1 << self.bcount-1)) >> self.bcount-1
|
||||
self.bcount -= 1
|
||||
return rv
|
||||
|
||||
def readbits(self, n):
|
||||
v = 0
|
||||
while n > 0:
|
||||
v = (v << 1) | self._readbit()
|
||||
n -= 1
|
||||
return v
|
||||
|
||||
if __name__ == '__main__':
|
||||
import os
|
||||
import sys
|
||||
# Determine this module's name from it's file name and import it.
|
||||
module_name = os.path.splitext(os.path.basename(__file__))[0]
|
||||
bitio = __import__(module_name)
|
||||
|
||||
with open('bitio_test.dat', 'wb') as outfile:
|
||||
with bitio.BitWriter(outfile) as writer:
|
||||
chars = '12345abcde'
|
||||
for ch in chars:
|
||||
writer.writebits(ord(ch), 7)
|
||||
|
||||
with open('bitio_test.dat', 'rb') as infile:
|
||||
with bitio.BitReader(infile) as reader:
|
||||
chars = []
|
||||
while True:
|
||||
x = reader.readbits(7)
|
||||
if not reader.read: # End-of-file?
|
||||
break
|
||||
chars.append(chr(x))
|
||||
print(''.join(chars))
|
||||
9
Task/Bitwise-IO/Python/bitwise-io-2.py
Normal file
9
Task/Bitwise-IO/Python/bitwise-io-2.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import sys
|
||||
import bitio
|
||||
|
||||
o = bitio.BitWriter(sys.stdout)
|
||||
c = sys.stdin.read(1)
|
||||
while len(c) > 0:
|
||||
o.writebits(ord(c), 7)
|
||||
c = sys.stdin.read(1)
|
||||
o.flush()
|
||||
9
Task/Bitwise-IO/Python/bitwise-io-3.py
Normal file
9
Task/Bitwise-IO/Python/bitwise-io-3.py
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import sys
|
||||
import bitio
|
||||
|
||||
r = bitio.BitReader(sys.stdin)
|
||||
while True:
|
||||
x = r.readbits(7)
|
||||
if not r.read: # nothing read
|
||||
break
|
||||
sys.stdout.write(chr(x))
|
||||
26
Task/Bitwise-IO/REXX/bitwise-io-1.rexx
Normal file
26
Task/Bitwise-IO/REXX/bitwise-io-1.rexx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/* REXX ****************************************************************
|
||||
* 01.11.2012 Walter Pachl
|
||||
***********************************************************************/
|
||||
s='STRING' /* Test input */
|
||||
Say 's='s
|
||||
ol='' /* initialize target */
|
||||
Do While s<>'' /* loop through input */
|
||||
Parse Var s c +1 s /* pick a character */
|
||||
cx=c2x(c) /* convert to hex */
|
||||
cb=x2b(cx) /* convert to bits */
|
||||
ol=ol||substr(cb,2) /* append to target */
|
||||
End
|
||||
l=length(ol) /* current length */
|
||||
lm=l//8
|
||||
ol=ol||copies('0',8-lm) /* pad to multiple of 8 */
|
||||
pd=copies(' ',l)||copies('0',8-lm)
|
||||
Say 'b='ol /* show target */
|
||||
Say ' 'pd 'padding'
|
||||
r='' /* initialize result */
|
||||
Do While length(ol)>6 /* loop through target */
|
||||
Parse Var ol b +7 ol /* pick 7 bits */
|
||||
b='0'||b /* add a leading '0' */
|
||||
x=b2x(b) /* convert to hex */
|
||||
r=r||x2c(x) /* convert to character */
|
||||
End /* and append to result */
|
||||
Say 'r='r /* show result */
|
||||
14
Task/Bitwise-IO/REXX/bitwise-io-2.rexx
Normal file
14
Task/Bitwise-IO/REXX/bitwise-io-2.rexx
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*REXX pgm encodes/decodes/displays ASCII character strings as (7─bits) binary string.*/
|
||||
parse arg $; if $=='' then $= 'STRING' /*get optional argument; Use default ? */
|
||||
say ' input string=' $ /*display the input string to terminal.*/
|
||||
out= comp($); say ' encoded string=' out /*encode─► 7─bit binary string; display*/
|
||||
ori= dcomp(out); say ' decoded string=' ori /*decode─► 8─bit char " ; " */
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
comp: parse arg x; z=; do j=1 for length(x) /*convert─►right-justified 7-bit binary*/
|
||||
z= z || right( x2b( c2x( substr(x, j, 1) )), 7)
|
||||
end /*j*/; L= length(z); return left(z, L+(8-L//8)//8, 0)
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
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
|
||||
59
Task/Bitwise-IO/Racket/bitwise-io.rkt
Normal file
59
Task/Bitwise-IO/Racket/bitwise-io.rkt
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#lang racket
|
||||
|
||||
(require racket/fixnum)
|
||||
|
||||
(define (make-bit-writer file)
|
||||
(define o (open-output-file file #:exists 'truncate))
|
||||
(define b+len (cons 0 0))
|
||||
(define (write-some-bits! n len)
|
||||
(if (<= 8 len)
|
||||
(begin (write-byte (fxand n #xFF) o)
|
||||
(write-some-bits! (fxrshift n 8) (- len 8)))
|
||||
(set! b+len (cons n len))))
|
||||
(define write-bits
|
||||
(case-lambda
|
||||
[(n) (if (eof-object? n)
|
||||
(begin (when (positive? (cdr b+len)) (write-byte (car b+len) o))
|
||||
(close-output-port o))
|
||||
(write-bits n (integer-length n)))]
|
||||
[(n nbits)
|
||||
(when (< nbits (integer-length n))
|
||||
(error 'write-bits "integer bigger than number of bits"))
|
||||
(write-some-bits! (fxior (car b+len) (fxlshift n (cdr b+len)))
|
||||
(+ (cdr b+len) nbits))]))
|
||||
write-bits)
|
||||
|
||||
(define (make-bit-reader file)
|
||||
(define i (open-input-file file))
|
||||
(define b+len (cons 0 0))
|
||||
(define (read-some-bits wanted n len)
|
||||
(if (<= wanted len)
|
||||
(begin0 (fxand n (sub1 (expt 2 wanted)))
|
||||
(set! b+len (cons (fxrshift n wanted) (- len wanted))))
|
||||
(read-some-bits wanted (+ n (fxlshift (read-byte i) len)) (+ len 8))))
|
||||
(define (read-bits n)
|
||||
(if (eof-object? n)
|
||||
(close-input-port i)
|
||||
(read-some-bits n (car b+len) (cdr b+len))))
|
||||
read-bits)
|
||||
|
||||
(define (crunch str file)
|
||||
(define out (make-bit-writer file))
|
||||
(for ([b (in-bytes (string->bytes/utf-8 str))]) (out b 7))
|
||||
(out eof))
|
||||
|
||||
(define (decrunch file)
|
||||
(define in (make-bit-reader file))
|
||||
(define bs (for/list ([i (in-range (quotient (* 8 (file-size file)) 7))])
|
||||
(in 7)))
|
||||
(in eof)
|
||||
(bytes->string/utf-8 (list->bytes bs)))
|
||||
|
||||
(define orig
|
||||
(string-append "This is an ascii string that will be"
|
||||
" crunched, written, read and expanded."))
|
||||
|
||||
(crunch orig "crunched.out")
|
||||
|
||||
(printf "Decrunched string ~aequal to original.\n"
|
||||
(if (equal? orig (decrunch "crunched.out")) "" "NOT "))
|
||||
14
Task/Bitwise-IO/Raku/bitwise-io.raku
Normal file
14
Task/Bitwise-IO/Raku/bitwise-io.raku
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
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;
|
||||
58
Task/Bitwise-IO/Red/bitwise-io.red
Normal file
58
Task/Bitwise-IO/Red/bitwise-io.red
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
Red [
|
||||
Title: "Bitwise IO"
|
||||
Link: http://rosettacode.org/wiki/Bitwise_IO
|
||||
Source: https://github.com/vazub/rosetta-red
|
||||
File: "%bitwiseio.red"
|
||||
Rights: "Copyright (C) 2020 Vasyl Zubko. All rights reserved."
|
||||
License: "Blue Oak Model License - https://blueoakcouncil.org/license/1.0.0"
|
||||
Tabs: 4
|
||||
]
|
||||
|
||||
str-compress: function [
|
||||
"Compressesor"
|
||||
str [string!]
|
||||
][
|
||||
buf: copy ""
|
||||
bit-str: enbase/base str 2
|
||||
foreach [bit1 bit2 bit3 bit4 bit5 bit6 bit7 bit8] bit-str [
|
||||
append buf rejoin [bit2 bit3 bit4 bit5 bit6 bit7 bit8]
|
||||
]
|
||||
if (pad-bits: (length? buf) // 8) <> 0 [
|
||||
loop (8 - pad-bits) [append buf "0"]
|
||||
]
|
||||
debase/base buf 2
|
||||
]
|
||||
|
||||
str-expand: function [
|
||||
"Decompressor"
|
||||
bin-hex [binary!]
|
||||
][
|
||||
bit-str: enbase/base bin-hex 2
|
||||
filled: 0
|
||||
buf: copy []
|
||||
acc: copy ""
|
||||
foreach bit bit-str [
|
||||
append acc bit
|
||||
filled: filled + 1
|
||||
if filled = 7 [
|
||||
append buf debase/base rejoin ["0" acc] 2
|
||||
clear acc
|
||||
filled: 0
|
||||
]
|
||||
]
|
||||
if (last buf) = #{00} [take/last buf]
|
||||
rejoin buf
|
||||
]
|
||||
|
||||
; DEMO
|
||||
in-string: "Red forever!"
|
||||
compressed: str-compress in-string
|
||||
expanded: str-expand compressed
|
||||
prin [
|
||||
pad "Input (string): " 20 mold in-string newline newline
|
||||
pad "Input (bits): " 20 enbase/base in-string 2 newline
|
||||
pad "Compressed (bits): " 20 enbase/base compressed 2 newline newline
|
||||
pad "Input (hex): " 20 to-binary in-string newline
|
||||
pad "Compressed (hex): " 20 compressed newline newline
|
||||
pad "Expanded (string): " 20 mold to-string expanded
|
||||
]
|
||||
35
Task/Bitwise-IO/Ruby/bitwise-io.rb
Normal file
35
Task/Bitwise-IO/Ruby/bitwise-io.rb
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
def crunch(ascii)
|
||||
bitstring = ascii.bytes.collect {|b| "%07b" % b}.join
|
||||
[bitstring].pack("B*")
|
||||
end
|
||||
|
||||
def expand(binary)
|
||||
bitstring = binary.unpack("B*")[0]
|
||||
bitstring.scan(/[01]{7}/).collect {|b| b.to_i(2).chr}.join
|
||||
end
|
||||
|
||||
original = "This is an ascii string that will be crunched, written, read and expanded."
|
||||
puts "my ascii string is #{original.length} bytes"
|
||||
|
||||
filename = "crunched.out"
|
||||
|
||||
# write the compressed data
|
||||
File.open(filename, "w") do |fh|
|
||||
fh.binmode
|
||||
fh.print crunch(original)
|
||||
end
|
||||
|
||||
filesize = File.size(filename)
|
||||
puts "the file containing the crunched text is #{filesize} bytes"
|
||||
|
||||
# read and expand
|
||||
expanded = File.open(filename, "r") do |fh|
|
||||
fh.binmode
|
||||
expand(fh.read)
|
||||
end
|
||||
|
||||
if original == expanded
|
||||
puts "success"
|
||||
else
|
||||
puts "fail!"
|
||||
end
|
||||
161
Task/Bitwise-IO/Rust/bitwise-io.rust
Normal file
161
Task/Bitwise-IO/Rust/bitwise-io.rust
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
pub trait Codec<Input = u8> {
|
||||
type Output: Iterator<Item = u8>;
|
||||
|
||||
fn accept(&mut self, input: Input) -> Self::Output;
|
||||
fn finish(self) -> Self::Output;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BitDiscard {
|
||||
buf: u16, // Use the higher byte for storing the leftovers
|
||||
buf_bits: u8, // How many bits are valid in the buffer
|
||||
valid_len: u8, // How many bits to keep from the input
|
||||
shift_len: u8, // Pre-computed shift of the input byte
|
||||
}
|
||||
|
||||
impl BitDiscard {
|
||||
pub fn new(discard: u8) -> Self {
|
||||
assert!(discard < 8);
|
||||
|
||||
BitDiscard {
|
||||
buf: 0,
|
||||
buf_bits: 0,
|
||||
valid_len: 8 - discard,
|
||||
shift_len: 8 + discard,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Codec<u8> for BitDiscard {
|
||||
type Output = std::option::IntoIter<u8>;
|
||||
|
||||
fn accept(&mut self, input: u8) -> Self::Output {
|
||||
let add = ((input as u16) << self.shift_len) >> self.buf_bits;
|
||||
self.buf |= add;
|
||||
self.buf_bits += self.valid_len;
|
||||
|
||||
let result = if self.buf_bits >= 8 {
|
||||
let result = (self.buf >> 8) as u8;
|
||||
self.buf <<= 8;
|
||||
self.buf_bits -= 8;
|
||||
Some(result)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
result.into_iter()
|
||||
}
|
||||
|
||||
fn finish(self) -> Self::Output {
|
||||
let result = if self.buf_bits > 0 {
|
||||
Some((self.buf >> 8) as u8)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
result.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BitExpand {
|
||||
buf: u16, // For storing the leftovers
|
||||
buf_bits: u8, // How many bits are valid in the buffer
|
||||
valid_len: u8, // How many bits are valid in the input
|
||||
shift_len: u8, // How many bits to shift when expanding
|
||||
}
|
||||
|
||||
impl BitExpand {
|
||||
pub fn new(expand: u8) -> Self {
|
||||
assert!(expand < 8);
|
||||
|
||||
Self {
|
||||
buf: 0,
|
||||
buf_bits: 0,
|
||||
valid_len: 8 - expand,
|
||||
shift_len: 8 + expand,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Codec<u8> for BitExpand {
|
||||
type Output = BitExpandIter;
|
||||
|
||||
fn accept(&mut self, input: u8) -> Self::Output {
|
||||
let add = ((input as u16) << 8) >> self.buf_bits;
|
||||
self.buf |= add;
|
||||
self.buf_bits += 8;
|
||||
let buf = self.buf;
|
||||
let leftover = self.buf_bits % self.valid_len;
|
||||
let buf_bits = self.buf_bits - leftover;
|
||||
self.buf <<= buf_bits;
|
||||
self.buf_bits = leftover;
|
||||
|
||||
Self::Output {
|
||||
buf,
|
||||
buf_bits,
|
||||
shift_len: self.shift_len,
|
||||
valid_len: self.valid_len,
|
||||
}
|
||||
}
|
||||
|
||||
fn finish(self) -> Self::Output {
|
||||
Self::Output {
|
||||
buf: 0,
|
||||
buf_bits: 0,
|
||||
shift_len: 0,
|
||||
valid_len: self.valid_len,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BitExpandIter {
|
||||
buf: u16,
|
||||
buf_bits: u8,
|
||||
valid_len: u8,
|
||||
shift_len: u8,
|
||||
}
|
||||
|
||||
impl Iterator for BitExpandIter {
|
||||
type Item = u8;
|
||||
|
||||
fn next(&mut self) -> Option<u8> {
|
||||
if self.buf_bits < self.valid_len {
|
||||
None
|
||||
} else {
|
||||
let result = (self.buf >> self.shift_len) as u8;
|
||||
self.buf <<= self.valid_len;
|
||||
self.buf_bits -= self.valid_len;
|
||||
Some(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn process_bytes<C: Codec>(mut codec: C, bytes: &[u8]) -> Vec<u8> {
|
||||
let mut result: Vec<u8> = bytes.iter().flat_map(|byte| codec.accept(*byte)).collect();
|
||||
codec.finish().for_each(|byte| result.push(byte));
|
||||
result
|
||||
}
|
||||
|
||||
fn print_bytes(bytes: &[u8]) {
|
||||
for byte in bytes {
|
||||
print!("{:08b} ", byte);
|
||||
}
|
||||
println!();
|
||||
|
||||
for byte in bytes {
|
||||
print!("{:02x} ", byte);
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let original = b"STRINGIFY!";
|
||||
let discard = 1;
|
||||
print_bytes(&original[..]);
|
||||
let compressed = process_bytes(BitDiscard::new(discard), &original[..]);
|
||||
print_bytes(&compressed);
|
||||
let decompressed = process_bytes(BitExpand::new(discard), &compressed);
|
||||
print_bytes(&decompressed);
|
||||
}
|
||||
60
Task/Bitwise-IO/Seed7/bitwise-io.seed7
Normal file
60
Task/Bitwise-IO/Seed7/bitwise-io.seed7
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
$ include "seed7_05.s7i";
|
||||
include "bitdata.s7i";
|
||||
include "strifile.s7i";
|
||||
|
||||
const proc: initWriteAscii (inout file: outFile, inout integer: bitPos) is func
|
||||
begin
|
||||
outFile.bufferChar := '\0;';
|
||||
bitPos := 0;
|
||||
end func;
|
||||
|
||||
const proc: writeAscii (inout file: outFile, inout integer: bitPos, in string: ascii) is func
|
||||
local
|
||||
var char: ch is ' ';
|
||||
begin
|
||||
for ch range ascii do
|
||||
if ch > '\127;' then
|
||||
raise RANGE_ERROR;
|
||||
else
|
||||
putBitsMsb(outFile, bitPos, ord(ch), 7);
|
||||
end if;
|
||||
end for;
|
||||
end func;
|
||||
|
||||
const proc: finishWriteAscii (inout file: outFile, inout integer: bitPos) is func
|
||||
begin
|
||||
write(outFile, chr(ord(outFile.bufferChar)));
|
||||
end func;
|
||||
|
||||
const proc: initReadAscii (inout file: outFile, inout integer: bitPos) is func
|
||||
begin
|
||||
bitPos := 8;
|
||||
end func;
|
||||
|
||||
const func string: readAscii (inout file: inFile, inout integer: bitPos, in integer: length) is func
|
||||
result
|
||||
var string: stri is "";
|
||||
local
|
||||
var char: ch is ' ';
|
||||
begin
|
||||
while not eof(inFile) and length(stri) < length do
|
||||
ch := chr(getBitsMsb(inFile, bitPos, 7));
|
||||
if inFile.bufferChar <> EOF then
|
||||
stri &:= ch;
|
||||
end if;
|
||||
end while;
|
||||
end func;
|
||||
|
||||
const proc: main is func
|
||||
local
|
||||
var file: aFile is STD_NULL;
|
||||
var integer: bitPos is 0;
|
||||
begin
|
||||
aFile := openStrifile;
|
||||
initWriteAscii(aFile, bitPos);
|
||||
writeAscii(aFile, bitPos, "Hello, Rosetta Code!");
|
||||
finishWriteAscii(aFile, bitPos);
|
||||
seek(aFile, 1);
|
||||
initReadAscii(aFile, bitPos);
|
||||
writeln(literal(readAscii(aFile, bitPos, 100)));
|
||||
end func;
|
||||
48
Task/Bitwise-IO/Tcl/bitwise-io.tcl
Normal file
48
Task/Bitwise-IO/Tcl/bitwise-io.tcl
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package require Tcl 8.5
|
||||
|
||||
proc crunch {ascii} {
|
||||
binary scan $ascii B* bitstring
|
||||
# crunch: remove the extraneous leading 0 bit
|
||||
regsub -all {0(.{7})} $bitstring {\1} 7bitstring
|
||||
set padded "$7bitstring[string repeat 0 [expr {8 - [string length $7bitstring]%8}]]"
|
||||
return [binary format B* $padded]
|
||||
}
|
||||
|
||||
proc expand {binary} {
|
||||
binary scan $binary B* padded
|
||||
# expand the 7 bit segments with their leading 0 bit
|
||||
set bitstring "0[join [regexp -inline -all {.{7}} $padded] 0]"
|
||||
return [binary format B* $bitstring]
|
||||
}
|
||||
|
||||
proc crunch_and_write {ascii filename} {
|
||||
set fh [open $filename w]
|
||||
fconfigure $fh -translation binary
|
||||
puts -nonewline $fh [crunch $ascii]
|
||||
close $fh
|
||||
}
|
||||
|
||||
proc read_and_expand {filename} {
|
||||
set fh [open $filename r]
|
||||
fconfigure $fh -translation binary
|
||||
set input [read $fh [file size $filename]]
|
||||
close $fh
|
||||
return [expand $input]
|
||||
}
|
||||
|
||||
set original "This is an ascii string that will be crunched, written, read and expanded."
|
||||
puts "my ascii string is [string length $original] bytes"
|
||||
|
||||
set filename crunched.out
|
||||
crunch_and_write $original $filename
|
||||
|
||||
set filesize [file size $filename]
|
||||
puts "the file containing the crunched text is $filesize bytes"
|
||||
|
||||
set expanded [read_and_expand $filename]
|
||||
|
||||
if {$original eq $expanded} {
|
||||
puts "the expanded string is the same as the original"
|
||||
} else {
|
||||
error "not the same"
|
||||
}
|
||||
100
Task/Bitwise-IO/Wren/bitwise-io.wren
Normal file
100
Task/Bitwise-IO/Wren/bitwise-io.wren
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
import "io" for File
|
||||
|
||||
class BitFilter {
|
||||
construct new(name) {
|
||||
_name = name
|
||||
_accu = 0
|
||||
_bits = 0
|
||||
}
|
||||
|
||||
openWriter() {
|
||||
_bw = File.create(_name)
|
||||
}
|
||||
|
||||
openReader() {
|
||||
_br = File.open(_name)
|
||||
_offset = 0
|
||||
}
|
||||
|
||||
write(buf, start, nBits, shift) {
|
||||
var index = start + (shift/8).floor
|
||||
shift = shift % 8
|
||||
while (nBits != 0 || _bits >= 8) {
|
||||
while (_bits >= 8) {
|
||||
_bits = _bits - 8
|
||||
_bw.writeBytes(String.fromByte((_accu >> _bits) & 255))
|
||||
}
|
||||
while (_bits < 8 && nBits != 0) {
|
||||
var b = buf[index]
|
||||
_accu = (_accu << 1) | (((128 >> shift) & b) >> (7 - shift))
|
||||
nBits = nBits - 1
|
||||
_bits = _bits + 1
|
||||
shift = shift + 1
|
||||
if (shift == 8) {
|
||||
shift = 0
|
||||
index = index + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
read(buf, start, nBits, shift) {
|
||||
var index = start + (shift/8).floor
|
||||
shift = shift % 8
|
||||
while (nBits != 0) {
|
||||
while (_bits != 0 && nBits != 0) {
|
||||
var mask = 128 >> shift
|
||||
if ((_accu & (1 << (_bits - 1))) != 0) {
|
||||
buf[index] = (buf[index] | mask) & 255
|
||||
} else {
|
||||
buf[index] = (buf[index] & ~mask) & 255
|
||||
}
|
||||
nBits = nBits - 1
|
||||
_bits = _bits - 1
|
||||
shift = shift + 1
|
||||
if (shift >= 8) {
|
||||
shift = 0
|
||||
index = index + 1
|
||||
}
|
||||
}
|
||||
if (nBits == 0) break
|
||||
var byte = _br.readBytes(1, _offset).bytes[0]
|
||||
_accu = (_accu << 8) | byte
|
||||
_bits = _bits + 8
|
||||
_offset = _offset + 1
|
||||
}
|
||||
}
|
||||
|
||||
closeWriter() {
|
||||
if (_bits != 0) {
|
||||
_accu = _accu << (8 - _bits)
|
||||
_bw.writeBytes(String.fromByte(_accu & 255))
|
||||
}
|
||||
_bw.close()
|
||||
_accu = 0
|
||||
_bits = 0
|
||||
}
|
||||
|
||||
closeReader() {
|
||||
_br.close()
|
||||
_accu = 0
|
||||
_bits = 0
|
||||
_offset = 0
|
||||
}
|
||||
}
|
||||
|
||||
var s = "abcdefghijk".bytes.toList
|
||||
var f = "test.bin"
|
||||
var bf = BitFilter.new(f)
|
||||
|
||||
/* for each byte in s, write 7 bits skipping 1 */
|
||||
bf.openWriter()
|
||||
for (i in 0...s.count) bf.write(s, i, 7, 1)
|
||||
bf.closeWriter()
|
||||
|
||||
/* read 7 bits and expand to each byte of s2 skipping 1 bit */
|
||||
bf.openReader()
|
||||
var s2 = List.filled(s.count, 0)
|
||||
for (i in 0...s2.count) bf.read(s2, i, 7, 1)
|
||||
bf.closeReader()
|
||||
System.print(s2.map { |b| String.fromByte(b) }.join())
|
||||
29
Task/Bitwise-IO/Z80-Assembly/bitwise-io-1.z80
Normal file
29
Task/Bitwise-IO/Z80-Assembly/bitwise-io-1.z80
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
StoreBinaryString:
|
||||
;INPUT:
|
||||
; HL = SOURCE ADDRESS
|
||||
; DE = OUTPUT STRING RAM
|
||||
; BC = HOW MANY BYTES OF SOURCE DATA TO CONVERT
|
||||
ld a,(hl)
|
||||
push bc
|
||||
ld b,a ;backup a for later
|
||||
ld c,%10000000 ;a "revolving bit mask" is used to compare
|
||||
; each bit of A, in sequence.
|
||||
loop:
|
||||
ld a,b ;restore A
|
||||
and c
|
||||
ld a,'0' ;get ascii 0 into A. This does not affect the flags!
|
||||
jr z,skip ;this jump is based on the result of B AND C
|
||||
inc a ;convert ascii 0 into ascii 1, only if B AND C was nonzero.
|
||||
skip:
|
||||
LD (DE),A ;store in output string
|
||||
inc de ;next byte of output string
|
||||
rrc c ;shift the bit mask down to the next bit of A
|
||||
jr nc,loop ;once a 1 is shifted into the carry, we're finished. Otherwise, check next bit.
|
||||
|
||||
pop bc
|
||||
inc hl
|
||||
dec bc
|
||||
ld a,b
|
||||
or c
|
||||
jp nz,StoreBinaryString
|
||||
ret
|
||||
41
Task/Bitwise-IO/Z80-Assembly/bitwise-io-2.z80
Normal file
41
Task/Bitwise-IO/Z80-Assembly/bitwise-io-2.z80
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
CompressBinaryStrings_7bit:
|
||||
; HL = pointer to output
|
||||
; DE = pointer to input. Input is assumed to equal &30 or &31
|
||||
; Usage:
|
||||
; LD hl,OutputRam
|
||||
; LD de,InputRam
|
||||
; CALL CompressBinaryStrings_7bit
|
||||
|
||||
; If the string "runs out" before the 8 bit boundary, the rest are rotated into place.
|
||||
; e.g. input = "0101" then the procedure will RLC until those bits
|
||||
; are as far left as possible.
|
||||
|
||||
outerloop:
|
||||
inc de ;skip bit 7
|
||||
ld b,7 ;loop counter
|
||||
innerloop:
|
||||
ld a,(de)
|
||||
or a ;compares accumulator to zero. Assumes a null-terminated string.
|
||||
; Otherwise compare A to your terminator of choice.
|
||||
|
||||
jr z,HandleEarlyExit
|
||||
;input is assumed to be &30 or &31, so the least significant bit tells us
|
||||
; all we need to know. The rest of the byte can be discarded.
|
||||
|
||||
rra ;rotate the result into the carry
|
||||
rl (hl) ;rotate it out of the carry into (HL)
|
||||
inc de
|
||||
z_djnz innerloop
|
||||
;a macro that becomes DJNZ <label> on Zilog Z80 and DEC B JR NZ,<label> on Sharp LR35902
|
||||
|
||||
inc hl ;next output byte
|
||||
jp outerloop
|
||||
|
||||
HandleEarlyExit:
|
||||
xor a ;LD A,0
|
||||
cp b ;compare B to zero
|
||||
ret z ;if B=0, we're done. No need to adjust the last byte
|
||||
loop_earlyExit
|
||||
rlc (hl)
|
||||
z_djnz loop_earlyExit
|
||||
ret
|
||||
13
Task/Bitwise-IO/Zkl/bitwise-io-1.zkl
Normal file
13
Task/Bitwise-IO/Zkl/bitwise-io-1.zkl
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// stream of numBits sized ints to bytes, numBits<8
|
||||
fcn toBytes(n,[(numBits,acc,bitsSoFar)]state){
|
||||
acc=acc.shiftLeft(numBits) + n; bitsSoFar+=numBits;
|
||||
reg r;
|
||||
if(bitsSoFar>=8){
|
||||
bitsSoFar-=8;
|
||||
r=acc.shiftRight(bitsSoFar);
|
||||
acc=acc.bitAnd((-1).shiftLeft(bitsSoFar).bitNot());
|
||||
}
|
||||
else r=Void.Skip; // need more bits to make a byte
|
||||
state.clear(numBits,acc,bitsSoFar);
|
||||
r
|
||||
}
|
||||
7
Task/Bitwise-IO/Zkl/bitwise-io-2.zkl
Normal file
7
Task/Bitwise-IO/Zkl/bitwise-io-2.zkl
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
ns:="THIS IS A TEST".pump(List,"toAsc",'-(0x20));
|
||||
ns.println(ns.len());
|
||||
|
||||
state:=L(6,0,0,L()); // input is six bits wide
|
||||
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());
|
||||
12
Task/Bitwise-IO/Zkl/bitwise-io-3.zkl
Normal file
12
Task/Bitwise-IO/Zkl/bitwise-io-3.zkl
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// stream of bytes to numBits sized ints, 1<numBits<32
|
||||
fcn fromBytes(n,[(numBits,acc,bitsSoFar,buf)]state){
|
||||
acc=acc.shiftLeft(8) + n; bitsSoFar+=8;
|
||||
buf.clear();
|
||||
while(bitsSoFar>=numBits){
|
||||
bitsSoFar-=numBits;
|
||||
buf.append(acc.shiftRight(bitsSoFar));
|
||||
acc=acc.bitAnd((-1).shiftLeft(bitsSoFar).bitNot());
|
||||
}
|
||||
state.clear(numBits,acc,bitsSoFar,buf);
|
||||
return(Void.Write,Void.Write,buf); // append contents of buf to result
|
||||
}
|
||||
4
Task/Bitwise-IO/Zkl/bitwise-io-4.zkl
Normal file
4
Task/Bitwise-IO/Zkl/bitwise-io-4.zkl
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
state:=L(6,0,0,L()); // output is six bits wide
|
||||
r:=cns.pump(List,fromBytes.fp1(state)); // cns could be a file or ...
|
||||
r.println(r.len());
|
||||
r.pump(String,'+(0x20),"toChar").println();
|
||||
Loading…
Add table
Add a link
Reference in a new issue