@@ -2,14 +2,21 @@ package bits
2
2
3
3
import (
4
4
"embed"
5
+ "encoding/binary"
6
+ "fmt"
7
+ "math"
5
8
6
9
"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"
7
13
"github.com/wader/fq/pkg/decode"
8
14
"github.com/wader/fq/pkg/interp"
9
15
"github.com/wader/fq/pkg/scalar"
10
16
)
11
17
12
18
//go:embed bits.md
19
+ //go:embed bits.jq
13
20
//go:embed bytes.md
14
21
var bitsFS embed.FS
15
22
@@ -39,5 +46,74 @@ func init() {
39
46
DecodeFn : decodeBits (8 ),
40
47
SkipDecodeFunction : true , // skip add bytes and frombytes function
41
48
})
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
+
42
118
interp .RegisterFS (bitsFS )
43
119
}
0 commit comments