more ByteStream functions

This commit is contained in:
2022-06-10 21:50:16 +00:00
parent 9263a11a5c
commit f44ca0bb48

View File

@@ -3,12 +3,19 @@ package kiss;
import sys.io.File; import sys.io.File;
import haxe.io.Bytes; import haxe.io.Bytes;
using StringTools;
class ByteStream { class ByteStream {
var bytes = Bytes.alloc(0); var bytes = Bytes.alloc(0);
var position = 0; var position = 0;
var file = ""; var file = "";
function new () {} function new () {}
function posToPrint(?pos:Int) {
if (pos == null) pos = position;
return 'position $pos (0x${pos.hex()})';
}
public static function fromFile(file) { public static function fromFile(file) {
var s = new ByteStream(); var s = new ByteStream();
s.bytes = File.getBytes(file); s.bytes = File.getBytes(file);
@@ -41,20 +48,20 @@ class ByteStream {
public function readCString(maxLength = 0):String { public function readCString(maxLength = 0):String {
var string = ""; var string = "";
var pos = position; var pos = position;
var _maxBytes = if (maxLength <= 0) bytes.length - position else maxLength; // TODO test this for off-by-one error var _maxBytes = if (maxLength <= 0) bytes.length - position else maxLength + 1; // TODO test this for off-by-one error
for (idx in 0..._maxBytes) { for (idx in 0..._maxBytes) {
var next = readByte(); var next = readByte();
if (next == 0) { if (next == 0) {
if (maxLength > 0) if (maxLength > 0)
paddingBytes(_maxBytes - idx); paddingBytes(_maxBytes - idx - 1);
return string; return string;
} }
else string += String.fromCharCode(next); else string += String.fromCharCode(next);
} }
if (maxLength <= 0) { if (maxLength <= 0) {
throw 'C String starting at byte $pos in $file ends in unexpected EOF'; throw 'C String starting at ${posToPrint()} in $file ends in unexpected EOF';
} else { } else {
throw 'C String starting at byte $pos in $file is longer than $maxLength bytes: $string'; throw 'C String starting at ${posToPrint()} in $file is longer than $maxLength bytes: $string';
} }
} }
@@ -65,11 +72,30 @@ class ByteStream {
} }
public function unknownBytes(num:Int) { public function unknownBytes(num:Int) {
trace('Warning: ignoring $num unknown bytes starting at $position in $file'); trace('Warning: ignoring $num unknown bytes starting at ${posToPrint()} in $file');
paddingBytes(num); paddingBytes(num);
} }
public function paddingBytes(num) { public function paddingBytes(num) {
for (_ in 0...num) readByte(); for (_ in 0...num) readByte();
} }
public function paddingUntil(pos:String) {
var nextPos = Std.parseInt(pos);
if (nextPos <= position) {
throw 'given position $pos ($nextPos) is <= stream ${posToPrint()} in $file';
}
paddingBytes(nextPos - position);
return nextPos - position;
}
public function unknownUntil(pos:String) {
var startPos = position;
var num = paddingUntil(pos);
trace('Warning: ignoring $num unknown bytes starting at ${posToPrint(startPos)} in $file');
}
public function tracePosition() {
trace('$file: ${posToPrint()}');
}
} }