@@ -18,6 +18,7 @@ import (
1818 "bytes"
1919 "errors"
2020 "reflect"
21+ "sort"
2122 "sync"
2223
2324 _cbor "github.com/fxamacker/cbor/v2"
@@ -132,3 +133,54 @@ func (i IndefLengthByteString) MarshalCBOR() ([]byte, error) {
132133 )
133134 return ret , nil
134135}
136+
137+ type IndefLengthMap map [any ]any
138+
139+ func (i IndefLengthMap ) MarshalCBOR () ([]byte , error ) {
140+ ret := []byte {
141+ // Start indefinite-length map
142+ 0xbf ,
143+ }
144+
145+ // Collect keys and sort them by their CBOR encoding for deterministic output
146+ type keyValue struct {
147+ key any
148+ keyCbor []byte
149+ value any
150+ }
151+
152+ kvPairs := make ([]keyValue , 0 , len (map [any ]any (i )))
153+ for key , value := range map [any ]any (i ) {
154+ keyData , err := Encode (key )
155+ if err != nil {
156+ return nil , err
157+ }
158+ kvPairs = append (kvPairs , keyValue {
159+ key : key ,
160+ keyCbor : keyData ,
161+ value : value ,
162+ })
163+ }
164+
165+ // Sort by CBOR-encoded key for deterministic ordering
166+ sort .Slice (kvPairs , func (a , b int ) bool {
167+ return bytes .Compare (kvPairs [a ].keyCbor , kvPairs [b ].keyCbor ) < 0
168+ })
169+
170+ // Encode in sorted order
171+ for _ , kv := range kvPairs {
172+ ret = append (ret , kv .keyCbor ... )
173+ valueData , err := Encode (kv .value )
174+ if err != nil {
175+ return nil , err
176+ }
177+ ret = append (ret , valueData ... )
178+ }
179+
180+ ret = append (
181+ ret ,
182+ // End indefinite length map
183+ byte (0xff ),
184+ )
185+ return ret , nil
186+ }
0 commit comments