mirror of
https://bitbucket.org/s_l_teichmann/mtsatellite
synced 2025-02-05 12:20:23 +01:00
Factor out big endian reader
This commit is contained in:
parent
e36b61adbe
commit
8f0935a245
80
common/bigendianreader.go
Normal file
80
common/bigendianreader.go
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Copyright 2024 by Sascha L. Teichmann
|
||||||
|
// Use of this source code is governed by the MIT license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type bigEndianReader struct {
|
||||||
|
parent io.Reader
|
||||||
|
buf [4]byte
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ber *bigEndianReader) u8() (uint8, error) {
|
||||||
|
if ber.err != nil {
|
||||||
|
return 0, ber.err
|
||||||
|
}
|
||||||
|
_, err := io.ReadFull(ber.parent, ber.buf[:1])
|
||||||
|
if err != nil {
|
||||||
|
ber.err = err
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return ber.buf[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ber *bigEndianReader) u16() (uint16, error) {
|
||||||
|
if ber.err != nil {
|
||||||
|
return 0, ber.err
|
||||||
|
}
|
||||||
|
two := ber.buf[:2]
|
||||||
|
_, err := io.ReadFull(ber.parent, two)
|
||||||
|
if err != nil {
|
||||||
|
ber.err = err
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return binary.BigEndian.Uint16(two), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ber *bigEndianReader) u32() (uint32, error) {
|
||||||
|
if ber.err != nil {
|
||||||
|
return 0, ber.err
|
||||||
|
}
|
||||||
|
four := ber.buf[:2]
|
||||||
|
_, err := io.ReadFull(ber.parent, four)
|
||||||
|
if err != nil {
|
||||||
|
ber.err = err
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return binary.BigEndian.Uint32(four), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ber *bigEndianReader) str(n int) (string, error) {
|
||||||
|
if ber.err != nil {
|
||||||
|
return "", ber.err
|
||||||
|
}
|
||||||
|
buf := make([]byte, n)
|
||||||
|
_, err := io.ReadFull(ber.parent, buf)
|
||||||
|
if err != nil {
|
||||||
|
ber.err = err
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ber *bigEndianReader) full(n int) ([]byte, error) {
|
||||||
|
if ber.err != nil {
|
||||||
|
return nil, ber.err
|
||||||
|
}
|
||||||
|
buf := make([]byte, n)
|
||||||
|
_, err := io.ReadFull(ber.parent, buf)
|
||||||
|
if err != nil {
|
||||||
|
ber.err = err
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buf, nil
|
||||||
|
}
|
106
common/block.go
106
common/block.go
@ -92,101 +92,38 @@ type posBuf struct {
|
|||||||
Pos int
|
Pos int
|
||||||
}
|
}
|
||||||
|
|
||||||
type bigEndian struct {
|
|
||||||
data []byte
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (be *bigEndian) Err() error {
|
|
||||||
return be.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (be *bigEndian) u8() uint8 {
|
|
||||||
if be.err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if len(be.data) >= 1 {
|
|
||||||
x := be.data[0]
|
|
||||||
be.data = be.data[1:]
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
be.err = ErrBlockTruncated
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (be *bigEndian) u16() uint16 {
|
|
||||||
if be.err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if len(be.data) >= 2 {
|
|
||||||
x := binary.BigEndian.Uint16(be.data)
|
|
||||||
be.data = be.data[2:]
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
be.err = ErrBlockTruncated
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (be *bigEndian) u32() uint32 {
|
|
||||||
if be.err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if len(be.data) >= 4 {
|
|
||||||
x := binary.BigEndian.Uint32(be.data)
|
|
||||||
be.data = be.data[4:]
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
be.err = ErrBlockTruncated
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (be *bigEndian) str(l int) string {
|
|
||||||
if be.err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if len(be.data) >= l {
|
|
||||||
s := string(be.data[:l])
|
|
||||||
be.data = be.data[l:]
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
be.err = ErrBlockTruncated
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func decode29(data []byte, colors *Colors) (*DecodedBlock, error) {
|
func decode29(data []byte, colors *Colors) (*DecodedBlock, error) {
|
||||||
|
|
||||||
dec, err := zstd.NewReader(nil)
|
dec, err := zstd.NewReader(bytes.NewReader(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
content, err := dec.DecodeAll(data[1:], nil)
|
be := bigEndianReader{parent: dec}
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
be := bigEndian{data: content}
|
be.u8() // flags
|
||||||
|
be.u16() // lightning_complete
|
||||||
_ = be.u8() // flags
|
be.u32() // timestamp
|
||||||
_ = be.u16() // lightning_complete
|
be.u8() // name_id_mapping_version
|
||||||
_ = be.u32() // timestamp
|
|
||||||
_ = be.u8() // name_id_mapping_version
|
|
||||||
|
|
||||||
airID, ignoreID := int32(-1), int32(-1)
|
airID, ignoreID := int32(-1), int32(-1)
|
||||||
indexMap := make(map[int32]int32)
|
indexMap := make(map[int32]int32)
|
||||||
transparent := false
|
transparent := false
|
||||||
numNameIDMappings := be.u16()
|
numNameIDMappings, _ := be.u16()
|
||||||
for i := uint16(0); i < numNameIDMappings; i++ {
|
for i := uint16(0); i < numNameIDMappings; i++ {
|
||||||
id := int32(be.u16())
|
var (
|
||||||
name := be.str(int(be.u16()))
|
id, _ = be.u16()
|
||||||
|
nlen, _ = be.u16()
|
||||||
|
name, _ = be.str(int(nlen))
|
||||||
|
)
|
||||||
switch name {
|
switch name {
|
||||||
case "air":
|
case "air":
|
||||||
airID = id
|
airID = int32(id)
|
||||||
case "ignore":
|
case "ignore":
|
||||||
ignoreID = id
|
ignoreID = int32(id)
|
||||||
default:
|
default:
|
||||||
if index, found := colors.NameIndex[name]; found {
|
if index, found := colors.NameIndex[name]; found {
|
||||||
indexMap[id] = index
|
indexMap[int32(id)] = index
|
||||||
if !transparent && colors.IsTransparent(index) {
|
if !transparent && colors.IsTransparent(index) {
|
||||||
transparent = true
|
transparent = true
|
||||||
}
|
}
|
||||||
@ -195,18 +132,13 @@ func decode29(data []byte, colors *Colors) (*DecodedBlock, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = be.u8() // content_width
|
be.u8() // content_width
|
||||||
_ = be.u8() // params_width
|
be.u8() // params_width
|
||||||
|
|
||||||
if err := be.Err(); err != nil {
|
mapContent, err := be.full(2 * 4096)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
|
||||||
|
|
||||||
mapContent := make([]byte, 2*4096)
|
|
||||||
if len(be.data) < len(mapContent) {
|
|
||||||
return nil, ErrBlockTruncated
|
return nil, ErrBlockTruncated
|
||||||
}
|
}
|
||||||
copy(mapContent, be.data)
|
|
||||||
|
|
||||||
return &DecodedBlock{
|
return &DecodedBlock{
|
||||||
Version: data[0],
|
Version: data[0],
|
||||||
|
Loading…
Reference in New Issue
Block a user