mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-13 15:34:38 +01:00
99 lines
2.1 KiB
Go
99 lines
2.1 KiB
Go
package nullcomp
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
)
|
|
|
|
// Decompress decompresses null-compressesed data.
|
|
func Decompress(compData []byte) ([]byte, error) {
|
|
r := bytes.NewReader(compData)
|
|
|
|
header := make([]byte, 16)
|
|
n, err := r.Read(header)
|
|
if err != nil {
|
|
return nil, err
|
|
} else if n != len(header) {
|
|
return nil, err
|
|
}
|
|
|
|
// Just return the data if it doesn't contain the cmp header.
|
|
if !bytes.Equal(header, []byte("cmp\x2020110113\x20\x20\x20\x00")) {
|
|
return compData, nil
|
|
}
|
|
|
|
var output []byte
|
|
for {
|
|
b, err := r.ReadByte()
|
|
if err == io.EOF {
|
|
break
|
|
} else if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if b == 0 {
|
|
// If it's a null byte, then the next byte is how many nulls to add.
|
|
nullCount, err := r.ReadByte()
|
|
if err == io.EOF {
|
|
break
|
|
} else if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
output = append(output, make([]byte, int(nullCount))...)
|
|
} else {
|
|
output = append(output, b)
|
|
}
|
|
}
|
|
|
|
return output, nil
|
|
}
|
|
|
|
// Compress null compresses give given data.
|
|
func Compress(rawData []byte) ([]byte, error) {
|
|
r := bytes.NewReader(rawData)
|
|
var output []byte
|
|
output = append(output, []byte("cmp\x2020110113\x20\x20\x20\x00")...)
|
|
for {
|
|
b, err := r.ReadByte()
|
|
if err == io.EOF {
|
|
break
|
|
} else if err != nil {
|
|
return nil, err
|
|
}
|
|
if b == 0 {
|
|
output = append(output, []byte{0x00}...)
|
|
// read to get null count
|
|
nullCount := 1
|
|
for {
|
|
i, err := r.ReadByte()
|
|
if err == io.EOF {
|
|
output = append(output, []byte{byte(nullCount)}...)
|
|
break
|
|
} else if i != 0 && nullCount != 0 {
|
|
r.UnreadByte()
|
|
output = append(output, []byte{byte(nullCount)}...)
|
|
break
|
|
} else if i != 0 && nullCount == 0 {
|
|
r.UnreadByte()
|
|
output = output[:len(output)-2]
|
|
output = append(output, []byte{byte(0xFF)}...)
|
|
break
|
|
} else if err != nil {
|
|
return nil, err
|
|
}
|
|
nullCount++
|
|
|
|
// Flush the null-count if it gets to 255, start on the next null count.
|
|
if nullCount == 255 {
|
|
output = append(output, []byte{0xFF, 0x00}...)
|
|
nullCount = 0
|
|
}
|
|
}
|
|
} else {
|
|
output = append(output, b)
|
|
}
|
|
}
|
|
return output, nil
|
|
}
|