mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2026-04-29 14:11:43 +00:00
167 lines
3.4 KiB
Haxe
167 lines
3.4 KiB
Haxe
package net;
|
|
|
|
import haxe.io.FPHelper;
|
|
import haxe.io.BytesOutput;
|
|
import haxe.io.BytesInput;
|
|
import haxe.io.Bytes;
|
|
|
|
class InputBitStream {
|
|
var data:Bytes;
|
|
var position:Int;
|
|
var shift:Int;
|
|
|
|
public function new(data:Bytes) {
|
|
this.data = data;
|
|
this.position = 0;
|
|
this.shift = 0;
|
|
}
|
|
|
|
inline function readBits(bits:Int = 8) {
|
|
if (this.shift + bits >= 8) {
|
|
var extra = (this.shift + bits) % 8;
|
|
var remain = bits - extra;
|
|
var first = data.get(position) >> shift;
|
|
var result = first;
|
|
this.position++;
|
|
if (extra > 0) {
|
|
var second = (data.get(position) & (0xFF >> (8 - extra))) << remain;
|
|
result |= second;
|
|
}
|
|
this.shift = extra;
|
|
return result;
|
|
} else {
|
|
var result = (data.get(position) >> shift) & (0xFF >> (8 - bits));
|
|
shift += bits;
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
public inline function readInt(bits:Int = 32) {
|
|
var value = 0;
|
|
var shift = 0;
|
|
while (bits > 0) {
|
|
value |= readBits(bits < 8 ? bits : 8) << shift;
|
|
shift += 8;
|
|
bits -= 8;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
public inline function readFlag() {
|
|
return readInt(1) != 0;
|
|
}
|
|
|
|
public inline function readByte() {
|
|
return readInt(8);
|
|
}
|
|
|
|
public inline function readUInt16() {
|
|
return readInt(16);
|
|
}
|
|
|
|
public inline function readInt32() {
|
|
return readInt(32);
|
|
}
|
|
|
|
public inline function readFloat() {
|
|
return FPHelper.i32ToFloat(readInt32());
|
|
}
|
|
|
|
public inline function readDouble() {
|
|
var lo = readInt32();
|
|
var hi = readInt32();
|
|
return FPHelper.i64ToDouble(lo, hi);
|
|
}
|
|
|
|
public inline function readString() {
|
|
var length = readUInt16();
|
|
var str = "";
|
|
var buf = new StringBuf();
|
|
for (i in 0...length) {
|
|
buf.addChar(readByte());
|
|
}
|
|
return buf.toString();
|
|
}
|
|
}
|
|
|
|
class OutputBitStream {
|
|
var data:BytesOutput;
|
|
var position:Int;
|
|
var shift:Int;
|
|
var lastByte:Int;
|
|
|
|
public function new(data:BytesOutput = null) {
|
|
this.data = data;
|
|
if (this.data == null)
|
|
this.data = new BytesOutput();
|
|
this.position = 0;
|
|
this.shift = 0;
|
|
this.lastByte = 0;
|
|
}
|
|
|
|
inline function writeBits(value:Int, bits:Int) {
|
|
value = value & (0xFF >> (8 - bits));
|
|
if (this.shift + bits >= 8) {
|
|
var extra = (shift + bits) % 8;
|
|
var remain = bits - extra;
|
|
|
|
var first = value & (0xFF >> (8 - remain));
|
|
lastByte |= first << shift;
|
|
|
|
var second = (value >> remain) & (0xFF >> (8 - extra));
|
|
this.data.writeByte(this.lastByte);
|
|
this.lastByte = second;
|
|
this.shift = extra;
|
|
} else {
|
|
lastByte |= (value << this.shift) & (0xFF >> (8 - bits - this.shift));
|
|
this.shift += bits;
|
|
}
|
|
}
|
|
|
|
public inline function writeInt(value:Int, bits:Int = 32) {
|
|
while (bits > 0) {
|
|
this.writeBits(value & 0xFF, bits < 8 ? bits : 8);
|
|
value >>= 8;
|
|
bits -= 8;
|
|
}
|
|
}
|
|
|
|
public inline function writeFlag(value:Bool) {
|
|
writeInt(value ? 1 : 0, 1);
|
|
}
|
|
|
|
public inline function writeByte(value:Int) {
|
|
writeInt(value, 8);
|
|
}
|
|
|
|
public inline function writeUInt16(value:Int) {
|
|
writeInt(value, 16);
|
|
}
|
|
|
|
public inline function writeInt32(value:Int) {
|
|
writeInt(value, 32);
|
|
}
|
|
|
|
public inline function getBytes() {
|
|
this.data.writeByte(this.lastByte);
|
|
return this.data.getBytes();
|
|
}
|
|
|
|
public inline function writeFloat(value:Float) {
|
|
writeInt(FPHelper.floatToI32(value), 32);
|
|
}
|
|
|
|
public inline function writeString(value:String) {
|
|
writeUInt16(value.length);
|
|
for (i in 0...value.length) {
|
|
writeByte(StringTools.fastCodeAt(value, i));
|
|
}
|
|
}
|
|
|
|
public inline function writeDouble(value:Float) {
|
|
var i64 = FPHelper.doubleToI64(value);
|
|
writeInt32(i64.low);
|
|
writeInt32(i64.high);
|
|
}
|
|
}
|