Skip to content

Instantly share code, notes, and snippets.

@complacentsee
Created January 17, 2026 19:10
Show Gist options
  • Select an option

  • Save complacentsee/b1dd92fc8c5d81cfa42463844f291462 to your computer and use it in GitHub Desktop.

Select an option

Save complacentsee/b1dd92fc8c5d81cfa42463844f291462 to your computer and use it in GitHub Desktop.
package merlz
import (
"bytes"
"errors"
"fmt"
)
var (
ErrInputTooShort = errors.New("input too short (<4)")
ErrOutputSmall = errors.New("output buffer too small")
ErrBadBackref = errors.New("bad backreference")
ErrTruncated = errors.New("truncated input")
)
type Status uint32
const (
StatusOKFinal Status = 4
StatusRawNoDecompress Status = 3
StatusDecompressFail Status = 2
)
func (s Status) String() string {
switch s {
case StatusOKFinal:
return "OKFinal(4)"
case StatusRawNoDecompress:
return "RawNoDecompress(3)"
case StatusDecompressFail:
return "DecompressFail(2)"
default:
return fmt.Sprintf("Status(%d)", uint32(s))
}
}
func Decompress(src []byte) ([]byte, error) {
// --- DEBUG: header/preview only ---
fmt.Printf("[Decompress] srcLen=%d firstBytes=%s\n", len(src), HexPrefix(src, 16))
if len(src) >= 2 {
ctrl0 := uint16(src[0]) | (uint16(src[1]) << 8)
fmt.Printf("[Decompress] firstCtrl=0x%04X (bytes %02X %02X)\n", ctrl0, src[0], src[1])
}
// ---------------------------------
// Same growth heuristic as your working code.
out := make([]byte, 0, len(src)*2)
i := 0
for i < len(src) {
// Need 2 bytes for ctrl
if i+1 >= len(src) {
break
}
ctrl := uint16(src[i]) | (uint16(src[i+1]) << 8)
i += 2
for t := 0; t < 16; t++ {
if i >= len(src) {
break
}
if (ctrl & 1) == 0 {
// literal
out = append(out, src[i])
i++
} else {
// backref: 2 bytes
if i+1 >= len(src) {
return nil, fmt.Errorf("merlz: truncated backref at %d", i)
}
b0 := src[i]
b1 := src[i+1]
i += 2
length := int(b0&0x0F) + 1
offset := int((uint16(b0&0xF0) << 4) | uint16(b1))
if offset == 0 {
for k := 0; k < length; k++ {
out = append(out, 0x00)
}
} else {
start := len(out) - offset
if start < 0 {
return nil, fmt.Errorf("merlz: invalid offset=%d outLen=%d", offset, len(out))
}
for k := 0; k < length; k++ {
out = append(out, out[start+k])
}
}
}
ctrl >>= 1
}
}
// --- DEBUG: summary only ---
fmt.Printf("[Decompress] outLen=%d\n", len(out))
// ---------------------------
return out, nil
}
// hexPrefix returns a compact hex string of up to n bytes (e.g. "FF FE 3C 00 ...").
func HexPrefix(b []byte, n int) string {
if len(b) == 0 {
return "<empty>"
}
if n > len(b) {
n = len(b)
}
const hexd = "0123456789ABCDEF"
buf := make([]byte, 0, n*3+4)
for i := 0; i < n; i++ {
if i > 0 {
buf = append(buf, ' ')
}
v := b[i]
buf = append(buf, hexd[v>>4], hexd[v&0x0F])
}
if n < len(b) {
buf = append(buf, ' ', '.', '.', '.')
}
return string(buf)
}
func Compress(data []byte) []byte {
if len(data) == 0 {
return nil
}
var out bytes.Buffer
i := 0
for i < len(data) {
// Reserve space for flags
flagsPos := out.Len()
out.WriteByte(0)
out.WriteByte(0)
var flags uint16
bit := 0
for bit < 16 && i < len(data) {
bestLen := 0
bestOff := 0
// Search backward up to 4095 bytes
start := i - 4095
if start < 0 {
start = 0
}
// Greedy longest match up to 16 bytes
for j := i - 1; j >= start; j-- {
off := i - j
if off <= 0 || off > 4095 {
continue
}
l := 0
for l < 16 && i+l < len(data) && data[j+l] == data[i+l] {
l++
}
if l > bestLen {
bestLen = l
bestOff = off
if bestLen == 16 {
break
}
}
}
// Emit backref only if it helps
if bestLen >= 2 {
flags |= (1 << bit)
// Encode offset + length into 2 bytes:
// offset = ((b0&0xF0)<<4) | b1
// length = (b0&0x0F)+1
hi4 := byte((bestOff >> 8) & 0x0F) // upper 4 bits of offset
lo8 := byte(bestOff & 0xFF)
b0 := (hi4 << 4) | byte(bestLen-1)
b1 := lo8
out.WriteByte(b0)
out.WriteByte(b1)
i += bestLen
} else {
// literal
out.WriteByte(data[i])
i++
}
bit++
}
// Patch flags (little-endian)
buf := out.Bytes()
buf[flagsPos] = byte(flags & 0xFF)
buf[flagsPos+1] = byte((flags >> 8) & 0xFF)
}
return out.Bytes()
}
func CompressBlock(data []byte, unknowncontrolbyte byte) []byte {
n := len(data)
// raw empty
if n == 0 {
fmt.Printf("[CompressBlock] n=0 -> raw empty block\n")
return []byte{1, 0, 0, 0}
}
core := Compress(data)
// Decide raw vs compressed
raw := len(core) >= n
var out []byte
if raw {
out = make([]byte, 4+n)
out[0] = 1
copy(out[4:], data)
} else {
out = make([]byte, 4+len(core))
out[0] = 0
copy(out[4:], core)
}
//Specify compression type, just hard code since we only support the one.
out[1] = 0x00
out[2] = unknowncontrolbyte
out[3] = 0x00
// ---- DEBUG OUTPUT ----
encodedLen := int(out[1]) | int(out[2])<<8 | int(out[3])<<16
fmt.Printf(
"[CompressBlock] inputLen=%d encodedLen=0x%06X payloadLen=%d header=%02X %02X %02X %02X\n",
n,
encodedLen,
len(out),
out[0], out[1], out[2], out[3],
)
// Optional: show first few bytes of token stream too
if !raw && len(out) >= 10 {
fmt.Printf(
"[CompressBlock] first ctrl=%02X %02X next=%02X %02X %02X %02X\n",
out[4], out[5], out[6], out[7], out[8], out[9],
)
}
return out
}
func DecompressBlock(payload []byte) ([]byte, error) {
if len(payload) < 4 {
return nil, ErrInputTooShort
}
if payload[0] == 1 {
return append([]byte(nil), payload[4:]...), nil
}
return Decompress(payload[4:])
}
func CompressBlockTesting(data []byte) []byte {
n := len(data)
// empty raw block
if n == 0 {
return []byte{1, 0, 0, 0}
}
core := Compress(data)
// match Rockwell behavior: if compression isn't smaller, store raw
raw := len(core) >= n
var out []byte
if raw {
out = make([]byte, 4+n)
out[0] = 1
copy(out[4:], data)
} else {
out = make([]byte, 4+len(core))
out[0] = 0
copy(out[4:], core)
}
// bytes 1..3 = uncompressed length (24-bit LE)
out[1] = byte(n)
out[2] = byte(n >> 8)
out[3] = byte(n >> 16)
return out
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment