mirror of
https://github.com/wader/fq.git
synced 2024-12-22 21:01:37 +03:00
Merge pull request #615 from wader/float80-refactor
decode: Add float 80 reader
This commit is contained in:
commit
fcacd7e3a3
@ -202,7 +202,7 @@ func decodeASN1BERValue(d *decode.D, bib *bitio.Buffer, sb *strings.Builder, par
|
||||
case form == formConstructed || tag == universalTypeSequence || tag == universalTypeSet:
|
||||
d.FieldArray("constructed", func(d *decode.D) {
|
||||
for !d.End() {
|
||||
if length == lengthIndefinite && d.PeekBits(16) == lengthEndMarker {
|
||||
if length == lengthIndefinite && d.PeekUintBits(16) == lengthEndMarker {
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -71,14 +71,14 @@ func decodeBencodeValue(d *decode.D) {
|
||||
d.FieldUTF8("end", 1, d.StrAssert("e"))
|
||||
case "l":
|
||||
d.FieldArray("values", func(d *decode.D) {
|
||||
for d.PeekBits(8) != 'e' {
|
||||
for d.PeekUintBits(8) != 'e' {
|
||||
d.FieldStruct("value", decodeBencodeValue)
|
||||
}
|
||||
})
|
||||
d.FieldUTF8("end", 1, d.StrAssert("e"))
|
||||
case "d":
|
||||
d.FieldArray("pairs", func(d *decode.D) {
|
||||
for d.PeekBits(8) != 'e' {
|
||||
for d.PeekUintBits(8) != 'e' {
|
||||
d.FieldStruct("pair", func(d *decode.D) {
|
||||
d.FieldStruct("key", decodeBencodeValue)
|
||||
d.FieldStruct("value", decodeBencodeValue)
|
||||
|
@ -42,7 +42,7 @@ func decodeBitcoinBlock(d *decode.D) any {
|
||||
size := d.BitsLeft()
|
||||
|
||||
if bbi.HasHeader {
|
||||
magic := d.PeekBits(32)
|
||||
magic := d.PeekUintBits(32)
|
||||
switch magic {
|
||||
case 0xf9beb4d9,
|
||||
0x0b110907,
|
||||
|
@ -171,7 +171,7 @@ func decodeBitcoinScript(d *decode.D) any {
|
||||
}
|
||||
|
||||
for !d.End() {
|
||||
opcode := byte(d.PeekBits(8))
|
||||
opcode := byte(d.PeekUintBits(8))
|
||||
ope, ok := opcodeEntries.lookup(opcode)
|
||||
if !ok {
|
||||
d.Fatalf("unknown opcode %x", opcode)
|
||||
|
@ -49,7 +49,7 @@ func decodeBitcoinTranscation(d *decode.D) any {
|
||||
|
||||
d.FieldU32("version")
|
||||
witness := false
|
||||
if d.PeekBits(8) == 0 {
|
||||
if d.PeekUintBits(8) == 0 {
|
||||
witness = true
|
||||
d.FieldU8("marker")
|
||||
d.FieldU8("flag")
|
||||
|
@ -127,7 +127,7 @@ func bzip2Decode(d *decode.D) any {
|
||||
compressedSize := (readCompressedSize - compressedStart) - footerByteSize*8
|
||||
for i := 0; i < 8; i++ {
|
||||
d.SeekAbs(compressedStart + compressedSize)
|
||||
if d.PeekBits(48) == footerMagic {
|
||||
if d.PeekUintBits(48) == footerMagic {
|
||||
break
|
||||
}
|
||||
compressedSize--
|
||||
|
@ -124,7 +124,7 @@ func decodeCBORValue(d *decode.D) any {
|
||||
if shortCount == shortCountIndefinite {
|
||||
bb := &bytes.Buffer{}
|
||||
d.FieldArray("items", func(d *decode.D) {
|
||||
for d.PeekBits(8) != breakMarker {
|
||||
for d.PeekUintBits(8) != breakMarker {
|
||||
d.FieldStruct("item", func(d *decode.D) {
|
||||
v := decodeCBORValue(d)
|
||||
switch v := v.(type) {
|
||||
@ -149,7 +149,7 @@ func decodeCBORValue(d *decode.D) any {
|
||||
if shortCount == shortCountIndefinite {
|
||||
sb := &strings.Builder{}
|
||||
d.FieldArray("items", func(d *decode.D) {
|
||||
for d.PeekBits(8) != breakMarker {
|
||||
for d.PeekUintBits(8) != breakMarker {
|
||||
d.FieldStruct("item", func(d *decode.D) {
|
||||
v := decodeCBORValue(d)
|
||||
switch v := v.(type) {
|
||||
@ -171,7 +171,7 @@ func decodeCBORValue(d *decode.D) any {
|
||||
majorTypeArray: {s: scalar.Uint{Sym: "array"}, d: func(d *decode.D, shortCount uint64, count uint64) any {
|
||||
d.FieldArray("elements", func(d *decode.D) {
|
||||
for i := uint64(0); true; i++ {
|
||||
if shortCount == shortCountIndefinite && d.PeekBits(8) == breakMarker {
|
||||
if shortCount == shortCountIndefinite && d.PeekUintBits(8) == breakMarker {
|
||||
break
|
||||
} else if i >= count {
|
||||
break
|
||||
@ -187,7 +187,7 @@ func decodeCBORValue(d *decode.D) any {
|
||||
majorTypeMap: {s: scalar.Uint{Sym: "map"}, d: func(d *decode.D, shortCount uint64, count uint64) any {
|
||||
d.FieldArray("pairs", func(d *decode.D) {
|
||||
for i := uint64(0); true; i++ {
|
||||
if shortCount == shortCountIndefinite && d.PeekBits(8) == breakMarker {
|
||||
if shortCount == shortCountIndefinite && d.PeekUintBits(8) == breakMarker {
|
||||
break
|
||||
} else if i >= count {
|
||||
break
|
||||
|
@ -141,7 +141,7 @@ func fieldDecodeLabel(d *decode.D, pointerOffset int64, name string) {
|
||||
seenTermintor := false
|
||||
for !seenTermintor {
|
||||
d.FieldStruct("label", func(d *decode.D) {
|
||||
if d.PeekBits(2) == 0b11 {
|
||||
if d.PeekUintBits(2) == 0b11 {
|
||||
d.FieldU2("is_pointer")
|
||||
pointer := d.FieldU14("pointer")
|
||||
if endPos == 0 {
|
||||
|
@ -72,7 +72,7 @@ func gifDecode(d *decode.D) any {
|
||||
d.FieldArray("blocks", func(d *decode.D) {
|
||||
blocks:
|
||||
for {
|
||||
switch d.PeekBits(8) {
|
||||
switch d.PeekUintBits(8) {
|
||||
case ';':
|
||||
break blocks
|
||||
case '!': /* "!" */
|
||||
@ -89,7 +89,7 @@ func gifDecode(d *decode.D) any {
|
||||
d.FieldStruct("func_data_byte", func(d *decode.D) {
|
||||
byteCount := d.FieldU8("byte_count")
|
||||
b := d.FieldRawLen("data", int64(byteCount*8))
|
||||
if d.PeekBits(8) == 0 {
|
||||
if d.PeekUintBits(8) == 0 {
|
||||
d.FieldU8("terminator")
|
||||
seenTerminator = true
|
||||
}
|
||||
@ -135,7 +135,7 @@ func gifDecode(d *decode.D) any {
|
||||
d.FieldStruct("func_data_byte", func(d *decode.D) {
|
||||
byteCount := d.FieldU8("byte_count")
|
||||
d.FieldRawLen("data", int64(byteCount*8))
|
||||
if d.PeekBits(8) == 0 {
|
||||
if d.PeekUintBits(8) == 0 {
|
||||
d.FieldU8("terminator")
|
||||
seenTerminator = true
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ func init() {
|
||||
func id3v1Decode(d *decode.D) any {
|
||||
d.AssertAtLeastBitsLeft(128 * 8)
|
||||
d.FieldUTF8("magic", 3, d.StrAssert("TAG"))
|
||||
if d.PeekBits(8) == uint64('+') {
|
||||
if d.PeekUintBits(8) == uint64('+') {
|
||||
d.Errorf("looks like id3v11")
|
||||
}
|
||||
d.FieldUTF8NullFixedLen("song_name", 30)
|
||||
|
@ -315,7 +315,7 @@ func textNullLenFn(encoding int, notFoundFixedBytes int) func(d *decode.D) strin
|
||||
|
||||
d.SeekRel(nullLen * 8)
|
||||
// seems sometimes utf16 etc has one exta null byte
|
||||
if nullLen > 1 && d.PeekBits(8) == 0 {
|
||||
if nullLen > 1 && d.PeekUintBits(8) == 0 {
|
||||
d.SeekRel(8)
|
||||
}
|
||||
|
||||
@ -592,7 +592,7 @@ func decodeFrame(d *decode.D, version int) uint64 {
|
||||
func decodeFrames(d *decode.D, version int, size uint64) {
|
||||
d.FieldArray("frames", func(d *decode.D) {
|
||||
for size > 0 {
|
||||
if d.PeekBits(8) == 0 {
|
||||
if d.PeekUintBits(8) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ func jpegDecode(d *decode.D) any {
|
||||
if inECD {
|
||||
ecdLen := int64(0)
|
||||
for {
|
||||
if d.PeekBits(8) == 0xff && d.PeekBits(16) != 0xff00 {
|
||||
if d.PeekUintBits(8) == 0xff && d.PeekUintBits(16) != 0xff00 {
|
||||
break
|
||||
}
|
||||
d.SeekRel(8)
|
||||
|
@ -445,7 +445,7 @@ func matroskaDecode(d *decode.D) any {
|
||||
d.ArgAs(&mi)
|
||||
|
||||
ebmlHeaderID := uint64(0x1a45dfa3)
|
||||
if d.PeekBits(32) != ebmlHeaderID {
|
||||
if d.PeekUintBits(32) != ebmlHeaderID {
|
||||
d.Errorf("no EBML header found")
|
||||
}
|
||||
dc := &decodeContext{tracks: []*track{}}
|
||||
|
@ -295,7 +295,7 @@ func decodeBoxesWithParentData(ctx *decodeContext, d *decode.D, parentData any,
|
||||
|
||||
if d.BitsLeft() > 0 {
|
||||
// "Some sample descriptions terminate with four zero bytes that are not otherwise indicated."
|
||||
if d.BitsLeft() >= 32 && d.PeekBits(32) == 0 {
|
||||
if d.BitsLeft() >= 32 && d.PeekUintBits(32) == 0 {
|
||||
d.FieldU32("zero_terminator")
|
||||
}
|
||||
if d.BitsLeft() > 0 {
|
||||
@ -904,7 +904,7 @@ func decodeBox(ctx *decodeContext, d *decode.D, typ string) {
|
||||
decodeBoxes(ctx, d)
|
||||
case "meta":
|
||||
// TODO: meta box sometimes has a 4 byte unknown field? (flag/version?)
|
||||
maybeFlags := d.PeekBits(32)
|
||||
maybeFlags := d.PeekUintBits(32)
|
||||
if maybeFlags == 0 {
|
||||
// TODO: rename?
|
||||
d.FieldU32("maybe_flags")
|
||||
@ -1687,7 +1687,7 @@ func decodeBox(ctx *decodeContext, d *decode.D, typ string) {
|
||||
// TODO: better probe? ffmpeg uses box name heuristics?
|
||||
// if 16 length field seems to match assume box with length, language and value
|
||||
// otherwise decode as box with value rest of box
|
||||
probeLength := d.PeekBits(16)
|
||||
probeLength := d.PeekUintBits(16)
|
||||
// +2 for length field, +2 for language field
|
||||
if (probeLength+2+2)*8 == uint64(d.BitsLeft()) {
|
||||
length := d.FieldU16("length")
|
||||
|
@ -17,7 +17,7 @@ func init() {
|
||||
|
||||
func moreRBSPData(d *decode.D) bool {
|
||||
l := d.BitsLeft()
|
||||
return l >= 8 && d.PeekBits(8) != 0b1000_0000
|
||||
return l >= 8 && d.PeekUintBits(8) != 0b1000_0000
|
||||
}
|
||||
|
||||
func avcPPSDecode(d *decode.D) any {
|
||||
|
@ -36,7 +36,7 @@ type subStream struct {
|
||||
func pesDecode(d *decode.D) any {
|
||||
substreams := map[int]*subStream{}
|
||||
|
||||
prefix := d.PeekBits(24)
|
||||
prefix := d.PeekUintBits(24)
|
||||
if prefix != 0b0000_0000_0000_0000_0000_0001 {
|
||||
d.Errorf("no pes prefix found")
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ func pesPacketDecode(d *decode.D) any {
|
||||
|
||||
}
|
||||
case startCode == packHeader:
|
||||
isMPEG2 := d.PeekBits(2) == 0b01
|
||||
isMPEG2 := d.PeekUintBits(2) == 0b01
|
||||
if isMPEG2 {
|
||||
d.FieldU2("marker_bits0", mpegVersion)
|
||||
} else {
|
||||
@ -140,7 +140,7 @@ func pesPacketDecode(d *decode.D) any {
|
||||
d.FieldU1("packet_rate_restriction_flag")
|
||||
d.FieldU7("reserved")
|
||||
d.FieldArray("stream_bound_entries", func(d *decode.D) {
|
||||
for d.PeekBits(1) == 1 {
|
||||
for d.PeekUintBits(1) == 1 {
|
||||
d.FieldStruct("stream_bound_entry", func(d *decode.D) {
|
||||
d.FieldU8("stream_id")
|
||||
d.FieldU2("skip0")
|
||||
|
@ -48,7 +48,7 @@ var commandNames = scalar.UintMapSymStr{
|
||||
}
|
||||
|
||||
func rleValue(d *decode.D) (uint64, uint64, int) {
|
||||
p := uint(d.PeekBits(8))
|
||||
p := uint(d.PeekUintBits(8))
|
||||
|
||||
// match zero prefix
|
||||
switch {
|
||||
|
@ -4,7 +4,6 @@ package riff
|
||||
|
||||
import (
|
||||
"github.com/wader/fq/format"
|
||||
"github.com/wader/fq/internal/mathex"
|
||||
"github.com/wader/fq/pkg/decode"
|
||||
"github.com/wader/fq/pkg/interp"
|
||||
"github.com/wader/fq/pkg/scalar"
|
||||
@ -81,9 +80,7 @@ func aiffDecode(d *decode.D) any {
|
||||
d.FieldU32("num_sample_frames")
|
||||
d.FieldU16("sample_size")
|
||||
// TODO: support big float?
|
||||
d.FieldFltFn("sample_rate", func(d *decode.D) float64 {
|
||||
return mathex.NewFloat80FromBytes(d.BytesLen(10)).Float64()
|
||||
})
|
||||
d.FieldF80("sample_rate")
|
||||
return false, nil
|
||||
case "SSND":
|
||||
d.FieldU32("offset")
|
||||
|
@ -77,7 +77,7 @@ func amf0DecodeValue(d *decode.D) {
|
||||
l := d.FieldU16("length")
|
||||
d.FieldUTF8("value", int(l))
|
||||
})
|
||||
typ = d.PeekBits(8)
|
||||
typ = d.PeekUintBits(8)
|
||||
d.FieldStruct("value", amf0DecodeValue)
|
||||
})
|
||||
}
|
||||
@ -98,7 +98,7 @@ func amf0DecodeValue(d *decode.D) {
|
||||
l := d.FieldU16("length")
|
||||
d.FieldUTF8("value", int(l))
|
||||
})
|
||||
typ = d.PeekBits(8)
|
||||
typ = d.PeekUintBits(8)
|
||||
d.FieldStruct("value", amf0DecodeValue)
|
||||
})
|
||||
}
|
||||
@ -134,7 +134,7 @@ func amf0DecodeValue(d *decode.D) {
|
||||
l := d.FieldU16("length")
|
||||
d.FieldUTF8("value", int(l))
|
||||
})
|
||||
typ = d.PeekBits(8)
|
||||
typ = d.PeekUintBits(8)
|
||||
d.FieldStruct("value", amf0DecodeValue)
|
||||
})
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ func rtmpDecode(d *decode.D) any {
|
||||
var chunkSteamID uint64
|
||||
|
||||
fmt := d.FieldU2("fmt")
|
||||
switch d.PeekBits(6) {
|
||||
switch d.PeekUintBits(6) {
|
||||
case 0:
|
||||
// 64-319: 2 byte
|
||||
d.FieldU6("chunk_stream_id_prefix")
|
||||
|
@ -695,7 +695,7 @@ func decodeTLS(d *decode.D) any {
|
||||
tc.server.currentCipherSuit = ciphersuites.TLS_NULL_WITH_NULL_NULL
|
||||
tc.server.nextCipherSuit = ciphersuites.TLS_NULL_WITH_NULL_NULL
|
||||
|
||||
firstByte := d.PeekBits(8)
|
||||
firstByte := d.PeekUintBits(8)
|
||||
if firstByte&0x80 != 0 {
|
||||
d.FieldStruct("ssl_v2", func(d *decode.D) {
|
||||
decodeV2ClientHello(d, tc)
|
||||
|
@ -306,7 +306,7 @@ func (d *D) SharedReadBuf(n int) []byte {
|
||||
if len(*d.readBuf) < n {
|
||||
*d.readBuf = make([]byte, n)
|
||||
}
|
||||
return *d.readBuf
|
||||
return (*d.readBuf)[:n]
|
||||
}
|
||||
|
||||
func (d *D) FillGaps(r ranges.Range, namePrefix string) {
|
||||
@ -370,14 +370,35 @@ func (d *D) IOPanic(err error, op string) {
|
||||
panic(IOError{Err: err, Pos: d.Pos(), Op: op})
|
||||
}
|
||||
|
||||
// TryBits reads nBits bits from buffer
|
||||
func (d *D) TryBits(nBits int) ([]byte, error) {
|
||||
if nBits < 0 {
|
||||
return nil, fmt.Errorf("nBits must be >= 0 (%d)", nBits)
|
||||
}
|
||||
buf := d.SharedReadBuf(int(bitio.BitsByteCount(int64(nBits))))
|
||||
_, err := bitio.ReadFull(d.bitBuf, buf, int64(nBits))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf[:], nil
|
||||
}
|
||||
|
||||
// Bits reads nBits bits from buffer
|
||||
func (d *D) TryBits(nBits int) (uint64, error) {
|
||||
func (d *D) Bits(nBits int) []byte {
|
||||
b, err := d.TryBits(nBits)
|
||||
if err != nil {
|
||||
panic(IOError{Err: err, Op: "Bits", ReadSize: int64(nBits), Pos: d.Pos()})
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// TryUintBits reads nBits bits as a uint64 from buffer
|
||||
func (d *D) TryUintBits(nBits int) (uint64, error) {
|
||||
if nBits < 0 || nBits > 64 {
|
||||
return 0, fmt.Errorf("nBits must be 0-64 (%d)", nBits)
|
||||
}
|
||||
// 64 bits max, 9 byte worse case if not byte aligned
|
||||
buf := d.SharedReadBuf(9)
|
||||
_, err := bitio.ReadFull(d.bitBuf, buf, int64(nBits)) // TODO: int64?
|
||||
buf, err := d.TryBits(nBits)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -385,19 +406,19 @@ func (d *D) TryBits(nBits int) (uint64, error) {
|
||||
return bitio.Read64(buf[:], 0, int64(nBits)), nil // TODO: int64
|
||||
}
|
||||
|
||||
// Bits reads nBits bits from buffer
|
||||
func (d *D) Bits(nBits int) uint64 {
|
||||
n, err := d.TryBits(nBits)
|
||||
// UintBits reads nBits bits as uint64 from buffer
|
||||
func (d *D) UintBits(nBits int) uint64 {
|
||||
n, err := d.TryUintBits(nBits)
|
||||
if err != nil {
|
||||
panic(IOError{Err: err, Op: "Bits", ReadSize: int64(nBits), Pos: d.Pos()})
|
||||
panic(IOError{Err: err, Op: "UintBits", ReadSize: int64(nBits), Pos: d.Pos()})
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (d *D) PeekBits(nBits int) uint64 {
|
||||
func (d *D) PeekUintBits(nBits int) uint64 {
|
||||
n, err := d.TryPeekBits(nBits)
|
||||
if err != nil {
|
||||
panic(IOError{Err: err, Op: "PeekBits", ReadSize: int64(nBits), Pos: d.Pos()})
|
||||
panic(IOError{Err: err, Op: "PeekUintBits", ReadSize: int64(nBits), Pos: d.Pos()})
|
||||
}
|
||||
return n
|
||||
}
|
||||
@ -450,7 +471,7 @@ func (d *D) TryPeekBits(nBits int) (uint64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n, err := d.TryBits(nBits)
|
||||
n, err := d.TryUintBits(nBits)
|
||||
if _, err := d.bitBuf.SeekBits(start, io.SeekStart); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -18260,6 +18260,52 @@ func (d *D) FieldF64(name string, sms ...scalar.FltMapper) float64 {
|
||||
return d.FieldScalarF64(name, sms...).Actual
|
||||
}
|
||||
|
||||
// Reader F80
|
||||
|
||||
// TryF80 tries to read 80 bit IEEE 754 float in current endian
|
||||
func (d *D) TryF80() (float64, error) { return d.tryFEndian(80, d.Endian) }
|
||||
|
||||
// F80 reads 80 bit IEEE 754 float in current endian
|
||||
func (d *D) F80() float64 {
|
||||
v, err := d.tryFEndian(80, d.Endian)
|
||||
if err != nil {
|
||||
panic(IOError{Err: err, Op: "F80", Pos: d.Pos()})
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// TryFieldScalarF80 tries to add a field and read 80 bit IEEE 754 float in current endian
|
||||
func (d *D) TryFieldScalarF80(name string, sms ...scalar.FltMapper) (*scalar.Flt, error) {
|
||||
s, err := d.TryFieldScalarFltFn(name, func(d *D) (scalar.Flt, error) {
|
||||
v, err := d.tryFEndian(80, d.Endian)
|
||||
return scalar.Flt{Actual: v}, err
|
||||
}, sms...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s, err
|
||||
}
|
||||
|
||||
// FieldScalarF80 adds a field and reads 80 bit IEEE 754 float in current endian
|
||||
func (d *D) FieldScalarF80(name string, sms ...scalar.FltMapper) *scalar.Flt {
|
||||
s, err := d.TryFieldScalarF80(name, sms...)
|
||||
if err != nil {
|
||||
panic(IOError{Err: err, Name: name, Op: "F80", Pos: d.Pos()})
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// TryFieldF80 tries to add a field and read 80 bit IEEE 754 float in current endian
|
||||
func (d *D) TryFieldF80(name string, sms ...scalar.FltMapper) (float64, error) {
|
||||
s, err := d.TryFieldScalarF80(name, sms...)
|
||||
return s.Actual, err
|
||||
}
|
||||
|
||||
// FieldF80 adds a field and reads 80 bit IEEE 754 float in current endian
|
||||
func (d *D) FieldF80(name string, sms ...scalar.FltMapper) float64 {
|
||||
return d.FieldScalarF80(name, sms...).Actual
|
||||
}
|
||||
|
||||
// Reader F16LE
|
||||
|
||||
// TryF16LE tries to read 16 bit IEEE 754 float in little-endian
|
||||
@ -18398,6 +18444,52 @@ func (d *D) FieldF64LE(name string, sms ...scalar.FltMapper) float64 {
|
||||
return d.FieldScalarF64LE(name, sms...).Actual
|
||||
}
|
||||
|
||||
// Reader F80LE
|
||||
|
||||
// TryF80LE tries to read 80 bit IEEE 754 float in little-endian
|
||||
func (d *D) TryF80LE() (float64, error) { return d.tryFEndian(80, LittleEndian) }
|
||||
|
||||
// F80LE reads 80 bit IEEE 754 float in little-endian
|
||||
func (d *D) F80LE() float64 {
|
||||
v, err := d.tryFEndian(80, LittleEndian)
|
||||
if err != nil {
|
||||
panic(IOError{Err: err, Op: "F80LE", Pos: d.Pos()})
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// TryFieldScalarF80LE tries to add a field and read 80 bit IEEE 754 float in little-endian
|
||||
func (d *D) TryFieldScalarF80LE(name string, sms ...scalar.FltMapper) (*scalar.Flt, error) {
|
||||
s, err := d.TryFieldScalarFltFn(name, func(d *D) (scalar.Flt, error) {
|
||||
v, err := d.tryFEndian(80, LittleEndian)
|
||||
return scalar.Flt{Actual: v}, err
|
||||
}, sms...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s, err
|
||||
}
|
||||
|
||||
// FieldScalarF80LE adds a field and reads 80 bit IEEE 754 float in little-endian
|
||||
func (d *D) FieldScalarF80LE(name string, sms ...scalar.FltMapper) *scalar.Flt {
|
||||
s, err := d.TryFieldScalarF80LE(name, sms...)
|
||||
if err != nil {
|
||||
panic(IOError{Err: err, Name: name, Op: "F80LE", Pos: d.Pos()})
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// TryFieldF80LE tries to add a field and read 80 bit IEEE 754 float in little-endian
|
||||
func (d *D) TryFieldF80LE(name string, sms ...scalar.FltMapper) (float64, error) {
|
||||
s, err := d.TryFieldScalarF80LE(name, sms...)
|
||||
return s.Actual, err
|
||||
}
|
||||
|
||||
// FieldF80LE adds a field and reads 80 bit IEEE 754 float in little-endian
|
||||
func (d *D) FieldF80LE(name string, sms ...scalar.FltMapper) float64 {
|
||||
return d.FieldScalarF80LE(name, sms...).Actual
|
||||
}
|
||||
|
||||
// Reader F16BE
|
||||
|
||||
// TryF16BE tries to read 16 bit IEEE 754 float in big-endian
|
||||
@ -18536,6 +18628,52 @@ func (d *D) FieldF64BE(name string, sms ...scalar.FltMapper) float64 {
|
||||
return d.FieldScalarF64BE(name, sms...).Actual
|
||||
}
|
||||
|
||||
// Reader F80BE
|
||||
|
||||
// TryF80BE tries to read 80 bit IEEE 754 float in big-endian
|
||||
func (d *D) TryF80BE() (float64, error) { return d.tryFEndian(80, BigEndian) }
|
||||
|
||||
// F80BE reads 80 bit IEEE 754 float in big-endian
|
||||
func (d *D) F80BE() float64 {
|
||||
v, err := d.tryFEndian(80, BigEndian)
|
||||
if err != nil {
|
||||
panic(IOError{Err: err, Op: "F80BE", Pos: d.Pos()})
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// TryFieldScalarF80BE tries to add a field and read 80 bit IEEE 754 float in big-endian
|
||||
func (d *D) TryFieldScalarF80BE(name string, sms ...scalar.FltMapper) (*scalar.Flt, error) {
|
||||
s, err := d.TryFieldScalarFltFn(name, func(d *D) (scalar.Flt, error) {
|
||||
v, err := d.tryFEndian(80, BigEndian)
|
||||
return scalar.Flt{Actual: v}, err
|
||||
}, sms...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s, err
|
||||
}
|
||||
|
||||
// FieldScalarF80BE adds a field and reads 80 bit IEEE 754 float in big-endian
|
||||
func (d *D) FieldScalarF80BE(name string, sms ...scalar.FltMapper) *scalar.Flt {
|
||||
s, err := d.TryFieldScalarF80BE(name, sms...)
|
||||
if err != nil {
|
||||
panic(IOError{Err: err, Name: name, Op: "F80BE", Pos: d.Pos()})
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// TryFieldF80BE tries to add a field and read 80 bit IEEE 754 float in big-endian
|
||||
func (d *D) TryFieldF80BE(name string, sms ...scalar.FltMapper) (float64, error) {
|
||||
s, err := d.TryFieldScalarF80BE(name, sms...)
|
||||
return s.Actual, err
|
||||
}
|
||||
|
||||
// FieldF80BE adds a field and reads 80 bit IEEE 754 float in big-endian
|
||||
func (d *D) FieldF80BE(name string, sms ...scalar.FltMapper) float64 {
|
||||
return d.FieldScalarF80BE(name, sms...).Actual
|
||||
}
|
||||
|
||||
// Reader FP
|
||||
|
||||
// TryFP tries to read nBits fixed-point number in current endian
|
||||
|
@ -2,6 +2,7 @@ package decode
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
@ -20,7 +21,7 @@ func (d *D) tryUEndian(nBits int, endian Endian) (uint64, error) {
|
||||
if nBits < 0 {
|
||||
return 0, fmt.Errorf("tryUEndian nBits must be >= 0 (%d)", nBits)
|
||||
}
|
||||
n, err := d.TryBits(nBits)
|
||||
n, err := d.TryUintBits(nBits)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -88,20 +89,22 @@ func (d *D) tryFEndian(nBits int, endian Endian) (float64, error) {
|
||||
if nBits < 0 {
|
||||
return 0, fmt.Errorf("tryFEndian nBits must be >= 0 (%d)", nBits)
|
||||
}
|
||||
n, err := d.TryBits(nBits)
|
||||
b, err := d.TryBits(nBits)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if endian == LittleEndian {
|
||||
n = bitio.ReverseBytes64(nBits, n)
|
||||
ReverseBytes(b)
|
||||
}
|
||||
switch nBits {
|
||||
case 16:
|
||||
return float64(mathex.Float16(uint16(n)).Float32()), nil
|
||||
return float64(mathex.Float16(binary.BigEndian.Uint16(b)).Float32()), nil
|
||||
case 32:
|
||||
return float64(math.Float32frombits(uint32(n))), nil
|
||||
return float64(math.Float32frombits(binary.BigEndian.Uint32(b))), nil
|
||||
case 64:
|
||||
return math.Float64frombits(n), nil
|
||||
return math.Float64frombits(binary.BigEndian.Uint64(b)), nil
|
||||
case 80:
|
||||
return mathex.NewFloat80FromBytes(b).Float64(), nil
|
||||
default:
|
||||
return 0, fmt.Errorf("unsupported float size %d", nBits)
|
||||
}
|
||||
@ -111,7 +114,7 @@ func (d *D) tryFPEndian(nBits int, fBits int, endian Endian) (float64, error) {
|
||||
if nBits < 0 {
|
||||
return 0, fmt.Errorf("tryFPEndian nBits must be >= 0 (%d)", nBits)
|
||||
}
|
||||
n, err := d.TryBits(nBits)
|
||||
n, err := d.TryUintBits(nBits)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -160,7 +163,7 @@ func (d *D) tryTextLenPrefixed(lenBits int, fixedBytes int, e encoding.Encoding)
|
||||
}
|
||||
|
||||
p := d.Pos()
|
||||
l, err := d.TryBits(lenBits)
|
||||
l, err := d.TryUintBits(lenBits)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -228,7 +231,7 @@ func (d *D) tryUnary(ov uint64) (uint64, error) {
|
||||
p := d.Pos()
|
||||
var n uint64
|
||||
for {
|
||||
b, err := d.TryBits(1)
|
||||
b, err := d.TryUintBits(1)
|
||||
if err != nil {
|
||||
d.SeekAbs(p)
|
||||
return 0, err
|
||||
@ -242,7 +245,7 @@ func (d *D) tryUnary(ov uint64) (uint64, error) {
|
||||
}
|
||||
|
||||
func (d *D) tryBool() (bool, error) {
|
||||
n, err := d.TryBits(1)
|
||||
n, err := d.TryUintBits(1)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -290,6 +290,13 @@
|
||||
"call" : "d.tryFEndian(64, d.Endian)" ,
|
||||
"doc" : "64 bit IEEE 754 float in current endian"
|
||||
},
|
||||
{
|
||||
"name" : "80" ,
|
||||
"args" : "" ,
|
||||
"params": "" ,
|
||||
"call" : "d.tryFEndian(80, d.Endian)" ,
|
||||
"doc" : "80 bit IEEE 754 float in current endian"
|
||||
},
|
||||
{
|
||||
"name" : "16LE" ,
|
||||
"args" : "" ,
|
||||
@ -311,6 +318,13 @@
|
||||
"call" : "d.tryFEndian(64, LittleEndian)" ,
|
||||
"doc" : "64 bit IEEE 754 float in little-endian"
|
||||
},
|
||||
{
|
||||
"name" : "80LE" ,
|
||||
"args" : "" ,
|
||||
"params": "" ,
|
||||
"call" : "d.tryFEndian(80, LittleEndian)" ,
|
||||
"doc" : "80 bit IEEE 754 float in little-endian"
|
||||
},
|
||||
{
|
||||
"name" : "16BE" ,
|
||||
"args" : "" ,
|
||||
@ -331,6 +345,13 @@
|
||||
"params": "" ,
|
||||
"call" : "d.tryFEndian(64, BigEndian)" ,
|
||||
"doc" : "64 bit IEEE 754 float in big-endian"
|
||||
},
|
||||
{
|
||||
"name" : "80BE" ,
|
||||
"args" : "" ,
|
||||
"params": "" ,
|
||||
"call" : "d.tryFEndian(80, BigEndian)" ,
|
||||
"doc" : "80 bit IEEE 754 float in big-endian"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user