@@ -2,14 +2,21 @@ package bits
22
33import (
44 "embed"
5+ "encoding/binary"
6+ "fmt"
7+ "math"
58
69 "github.com/wader/fq/format"
10+ "github.com/wader/fq/internal/gojqex"
11+ "github.com/wader/fq/internal/mathex"
12+ "github.com/wader/fq/pkg/bitio"
713 "github.com/wader/fq/pkg/decode"
814 "github.com/wader/fq/pkg/interp"
915 "github.com/wader/fq/pkg/scalar"
1016)
1117
1218//go:embed bits.md
19+ //go:embed bits.jq
1320//go:embed bytes.md
1421var bitsFS embed.FS
1522
@@ -39,5 +46,74 @@ func init() {
3946 DecodeFn : decodeBits (8 ),
4047 SkipDecodeFunction : true , // skip add bytes and frombytes function
4148 })
49+ interp .RegisterFunc2 ("_from_float" , func (_ * interp.Interp , c any , nBits int , isLE bool ) any {
50+ switch nBits {
51+ case 16 , 32 , 64 :
52+ default :
53+ return fmt .Errorf ("unsupported bit size %d, must be 16, 32 or 64" , nBits )
54+ }
55+
56+ br , err := interp .ToBitReader (c )
57+ if err != nil {
58+ return err
59+ }
60+ var b [8 ]byte
61+ bs := b [:][0 : nBits / 8 ]
62+ _ , err = br .ReadBits (bs [:], int64 (nBits ))
63+ if err != nil {
64+ return err
65+ }
66+ if isLE {
67+ decode .ReverseBytes (bs [:])
68+ }
69+
70+ switch nBits {
71+ case 64 :
72+ return math .Float64frombits (binary .BigEndian .Uint64 (bs [:]))
73+ case 32 :
74+ return float64 (math .Float32frombits (binary .BigEndian .Uint32 (bs [:])))
75+ case 16 :
76+ return float64 (mathex .Float16 (binary .BigEndian .Uint16 (bs [:])).Float32 ())
77+ default :
78+ panic ("unreachable" )
79+ }
80+ })
81+ interp .RegisterFunc2 ("_to_float" , func (_ * interp.Interp , c any , nBits int , isLE bool ) any {
82+ switch nBits {
83+ case 16 , 32 , 64 :
84+ default :
85+ return fmt .Errorf ("unsupported bit size %d, must be 16, 32 or 64" , nBits )
86+ }
87+
88+ v , ok := gojqex.Cast [float64 ](c )
89+ if ! ok {
90+ return gojqex.FuncTypeError {Name : "_to_float" , V : v }
91+ }
92+
93+ var b [8 ]byte
94+ bs := b [:][0 : nBits / 8 ]
95+ switch nBits {
96+ case 64 :
97+ binary .BigEndian .PutUint64 (bs , math .Float64bits (v ))
98+ case 32 :
99+ binary .BigEndian .PutUint32 (bs , math .Float32bits (float32 (v )))
100+ case 16 :
101+ binary .BigEndian .PutUint16 (bs , uint16 (mathex .NewFloat16 (float32 (v ))))
102+ default :
103+ panic ("unreachable" )
104+ }
105+ if isLE {
106+ decode .ReverseBytes (bs [:])
107+ }
108+
109+ br , err := interp .NewBinaryFromBitReader (bitio .NewBitReader (bs , - 1 ), 8 , 0 )
110+ if err != nil {
111+ return err
112+ }
113+
114+ return br
115+
116+ })
117+
42118 interp .RegisterFS (bitsFS )
43119}
0 commit comments