public bool WriteTo2(WriteBuffer buffer) { // 0. init header // 1. loop on header // 2. loop on Key, if any // 3. loop on Data, if any // 4. done switch (state) { case STATE_INITIAL: PrepareHeader(); state = STATE_WRITE_HEADER; goto case STATE_WRITE_HEADER; case STATE_WRITE_HEADER: writeOffset += buffer.Append(header, writeOffset, headerLength - writeOffset); if (writeOffset < headerLength) { return(true); } if (Key.Length > 0) { writeOffset = 0; state = STATE_WRITE_KEY; goto case STATE_WRITE_KEY; } goto case STATE_PREPARE_BODY; case STATE_WRITE_KEY: writeOffset += buffer.Append(Key.Array, writeOffset, Key.Length - writeOffset); if (writeOffset < Key.Length) { return(true); } goto case STATE_PREPARE_BODY; case STATE_PREPARE_BODY: if (Data.Count > 0) { writeOffset = 0; state = STATE_WRITE_BODY; goto case STATE_WRITE_BODY; } break; case STATE_WRITE_BODY: writeOffset += buffer.Append(Data.Array, Data.Offset + writeOffset, Data.Count - writeOffset); if (writeOffset < Data.Count) { return(true); } break; } state = STATE_DONE; return(false); }
private static ReadBuffer UnpackSequences(ReadBuffer packedData, byte seqMarker) { var remaining = packedData; var result = new WriteBuffer(); while (remaining.Length > 0) { var value = remaining[0]; remaining = remaining.Drop(1); if (value != seqMarker) { result.Append(value); } else { var sequence = remaining.TakeUntil(seqMarker); var count = remaining[sequence.Length + 1]; for (int i = 0; i < count; i++) { result.Append(sequence); } remaining = remaining.Drop(sequence.Length + 2); } } return(result.ToReadBuffer()); }
public bool WriteTo(WriteBuffer buffer) { // 0. init header // 1. loop on header // 2. loop on Key, if any // 3. loop on Data, if any // 4. done switch (state) { case STATE_INITIAL: goto init; case STATE_WRITE_HEADER: goto write_header; case STATE_WRITE_KEY: goto write_key; case STATE_WRITE_BODY: goto write_body; default: return false; } // TODO put these inside switch..case init: PrepareHeader(); state = STATE_WRITE_HEADER; write_header: writeOffset += buffer.Append(header, writeOffset, headerLength - writeOffset); if (writeOffset < headerLength) return true; if (Key.Length > 0) { writeOffset = 0; state = STATE_WRITE_KEY; } else goto pre_body; write_key: writeOffset += buffer.Append(Key.Array, writeOffset, Key.Length - writeOffset); if (writeOffset < Key.Length) return true; pre_body: if (Data.Count > 0) { writeOffset = 0; state = STATE_WRITE_BODY; } else goto done; write_body: writeOffset += buffer.Append(Data.Array, Data.Offset + writeOffset, Data.Count - writeOffset); if (writeOffset < Data.Count) return true; done: state = STATE_DONE; return false; }
private static ReadBuffer UnpackRLE(ReadBuffer packedData) { int escCount = packedData[0] & 0x7f; var escCodes = packedData.Slice(1, escCount); var rleData = packedData.Drop(escCount + 1); var escLookup = new byte[0x100]; for (int i = 0; i < escCount; i++) { escLookup[escCodes[i]] = (byte)(i + 1); } bool compressed = (packedData[0] & 0x80) == 0; var encodedData = compressed ? UnpackSequences(rleData, escCodes[1]) : rleData; var result = new WriteBuffer(); while (encodedData.Length > 0) { var code = escLookup[encodedData[0]]; switch (code) { case 0: result.Append(encodedData[0]); encodedData = encodedData.Drop(1); break; case 1: result.AppendRepeat(encodedData[2], encodedData[1]); encodedData = encodedData.Drop(3); break; case 3: result.AppendRepeat(encodedData[3], encodedData[1] + (((int)encodedData[2]) << 8)); encodedData = encodedData.Drop(4); break; default: result.AppendRepeat(encodedData[1], code - 1); encodedData = encodedData.Drop(2); break; } } return(result.ToReadBuffer()); }
private static ReadBuffer UnpackVLE(ReadBuffer packedData) { var widthsCount = packedData[0]; var widths = packedData.Slice(1, widthsCount); var alphabetCount = widths.Select(val => (int)val).Sum(); var alphabet = packedData.Slice(1 + widthsCount, alphabetCount); var dictionary = new HuffmanTree(widths, alphabet); var stream = EnumerateBits(packedData.Drop(1 + widthsCount + alphabetCount)); var result = new WriteBuffer(); while (true) { int value = dictionary.DecodeByte(stream); if (value < 0) { break; } result.Append((byte)value); } return(result.ToReadBuffer()); }
public bool WriteTo2(WriteBuffer buffer) { // 0. init header // 1. loop on header // 2. loop on Key, if any // 3. loop on Data, if any // 4. done switch (state) { case STATE_INITIAL: PrepareHeader(); state = STATE_WRITE_HEADER; goto case STATE_WRITE_HEADER; case STATE_WRITE_HEADER: writeOffset += buffer.Append(header, writeOffset, headerLength - writeOffset); if (writeOffset < headerLength) return true; if (Key.Length > 0) { writeOffset = 0; state = STATE_WRITE_KEY; goto case STATE_WRITE_KEY; } goto case STATE_PREPARE_BODY; case STATE_WRITE_KEY: writeOffset += buffer.Append(Key.Array, writeOffset, Key.Length - writeOffset); if (writeOffset < Key.Length) return true; goto case STATE_PREPARE_BODY; case STATE_PREPARE_BODY: if (Data.Count > 0) { writeOffset = 0; state = STATE_WRITE_BODY; goto case STATE_WRITE_BODY; } break; case STATE_WRITE_BODY: writeOffset += buffer.Append(Data.Array, Data.Offset + writeOffset, Data.Count - writeOffset); if (writeOffset < Data.Count) return true; break; } state = STATE_DONE; return false; }
public bool WriteTo(WriteBuffer buffer) { // 0. init header // 1. loop on header // 2. loop on Key, if any // 3. loop on Data, if any // 4. done switch (state) { case STATE_INITIAL: goto init; case STATE_WRITE_HEADER: goto write_header; case STATE_WRITE_KEY: goto write_key; case STATE_WRITE_BODY: goto write_body; default: return(false); } // TODO put these inside switch..case init: PrepareHeader(); state = STATE_WRITE_HEADER; write_header: writeOffset += buffer.Append(header, writeOffset, headerLength - writeOffset); if (writeOffset < headerLength) { return(true); } if (Key.Length > 0) { writeOffset = 0; state = STATE_WRITE_KEY; } else { goto pre_body; } write_key: writeOffset += buffer.Append(Key.Array, writeOffset, Key.Length - writeOffset); if (writeOffset < Key.Length) { return(true); } pre_body: if (Data.Count > 0) { writeOffset = 0; state = STATE_WRITE_BODY; } else { goto done; } write_body: writeOffset += buffer.Append(Data.Array, Data.Offset + writeOffset, Data.Count - writeOffset); if (writeOffset < Data.Count) { return(true); } done: state = STATE_DONE; return(false); }