Warning: session_start(): open(/var/lib/php/sessions/sess_9amnbnjaa87gm23glbpe00qu89, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
sclass HuffmanTree is BitIO {
settable Node root;
Leaf[] characterMap = new[256];
/*
algebraic Node {
constructor Branch {
settable Node zero;
settable Node one;
}
constructor Leaf {
settable byte literal;
}
}
*/
abstract class Node is BitIO {
settable Branch parent;
void buildSymbol(BitBuffer head, Node child) {
parent?.buildSymbol(head, this);
}
abstract Leaf readSymbol(BitHead head);
}
class Branch > Node {
gettable Node zero;
gettable Node one;
meta-for zero also as one {
selfType zero(Node zero) {
this.zero = zero;
zero.parent = this;
this;
}
}
public void readWrite(BitHead head) {
head.exchangeBit(1);
head.exchange(zero, -> zero(readNode(head)));
head.exchange(one, -> one(readNode(head)));
}
void buildSymbol(BitBuffer head, Node child) {
head.add(child == one);
super.buildSymbol(head, child);
}
Leaf readSymbol(BitHead head) {
bool bit = head.readBit();
print("Read bit " + bit);
ret (bit ? one : zero).readSymbol(head);
}
}
class Leaf > Node {
gettable byte literal;
*() {}
*(int literal) { literal((byte) literal); }
byte get() { ret literal; }
selfType literal(byte b) {
literal = b;
fillCharacterMap();
this;
}
public void readWrite(BitHead head) {
head.exchangeBit(0);
head.exchangeByte(literal, l1 literal);
print(this);
}
void fillCharacterMap {
characterMap[ubyteToInt(literal)] = this;
}
Leaf readSymbol(BitHead head) {
print("Reached symbol " + this);
this;
}
toString {
ret "Literal " + byteToHex(literal);
}
}
void makeRootIfEmpty {
root ifNull = new Leaf(0);
}
Node readNode(BitHead head) {
bool type = head.peekBit();
Node node = type ? new Branch : new Leaf;
print(type ? "Branch" : "Leaf");
node.readWrite(head);
ret node;
}
public void readWrite(BitHead head) {
if (head.writeMode()) {
makeRootIfEmpty();
root.readWrite(head);
}
if (head.readMode())
root = readNode(head);
}
toString {
makeRootIfEmpty();
new LS out;
new StringBuilder symbol;
embedded void toString_collect(Node node) {
if (node cast Leaf) {
out.add(symbol + ": " + /*ubyteToHex*/quote(codePoint(ubyteToInt(node!))));
} else {
cast node to Branch;
symbol.append("0");
toString_collect(node.zero());
removeLast(symbol);
symbol.append("1");
toString_collect(node.one());
removeLast(symbol);
}
}
toString_collect(root);
ret lines(out);
}
void writeCharacter aka writeSymbol(int sym, BitHead head) {
sym &= 0xFF;
Leaf node = characterMap[sym];
if (node == null)
fail("Symbol cannot be encoded: " + sym);
new BitBuffer buffer;
node.buildSymbol(buffer, null);
// when there is only one symbol
if (buffer.isEmpty())
buffer.add(0);
for (int i = l(buffer)-1; i >= 0; i--)
head.writeBit(buffer.get(i));
}
int readSymbol(BitHead head) {
if (head.isEOF()) ret -1;
if (root instanceof Leaf)
head.advanceBit(); // don't even care
ret ubyteToInt(root.readSymbol(head)!);
}
}