return
}
t = types.Raw
- v = &Raw{T: Type(tag), V: buf[1 : 1+l]}
+ v = Raw{T: Type(tag), V: buf[1 : 1+l]}
case TAI64, TAI64N, TAI64NA:
var l int
}
}
-func RawEncode(buf []byte, raw *Raw) []byte {
+func RawEncode(buf []byte, raw Raw) []byte {
return append(append(buf, byte(raw.T)), raw.V...)
}
return fmt.Sprintf("BLOB(%d, %d)", blob.ChunkLen, l)
}
-func MakeBlob(chunkLen int, data []byte) *Blob {
- blob := Blob{ChunkLen: chunkLen}
+func MakeBlob(chunkLen int, data []byte) (blob Blob) {
+ blob.ChunkLen = chunkLen
n := len(data) / chunkLen
for i := 0; i < n; i++ {
blob.Chunks = append(blob.Chunks, data[i*chunkLen:(i+1)*chunkLen])
if left > 0 {
blob.Chunks = append(blob.Chunks, data[len(data)-left:])
}
- return &blob
+ return
}
map[string]any{},
gyac.MakeBlob(123, []byte{}),
uuid.Nil,
- &atom.Raw{
+ atom.Raw{
T: atom.TAI64,
V: []byte("\x00\x00\x00\x00\x00\x00\x00\x00"),
},
time.Unix(1234567890, 0),
time.Unix(1234567890, 456*1000),
time.Unix(1234567890, 456789),
- &atom.Raw{
+ atom.Raw{
T: atom.TAI64NA,
V: []byte("\x40\x00\x00\x00\x49\x96\x02\xF4\x00\x06\xF8\x55\x07\x5B\xCD\x15"),
},
},
"floats": []any{
- &atom.Raw{T: atom.Float32, V: []byte("\x01\x02\x03\x04")},
+ atom.Raw{T: atom.Float32, V: []byte("\x01\x02\x03\x04")},
},
"uuid": uuid.MustParse("0e875e3f-d385-49eb-87b4-be42d641c367"),
}
tai.FromTime(t)
buf = atom.TAI64Encode(buf, tai[:])
}
- buf = atom.RawEncode(buf, &atom.Raw{
+ buf = atom.RawEncode(buf, atom.Raw{
T: atom.TAI64NA,
V: []byte("\x40\x00\x00\x00\x49\x96\x02\xF4\x00\x06\xF8\x55\x07\x5B\xCD\x15"),
})
{
buf = atom.StrEncode(buf, "floats")
buf = atom.ListEncode(buf)
- buf = atom.RawEncode(buf, &atom.Raw{
+ buf = atom.RawEncode(buf, atom.Raw{
T: atom.Float32,
V: []byte("\x01\x02\x03\x04"),
})
buf = atom.BinEncode(buf, []byte{})
}
buf = atom.UUIDEncode(buf, uuid.Nil)
- buf = atom.RawEncode(buf, &atom.Raw{
+ buf = atom.RawEncode(buf, atom.Raw{
T: atom.TAI64,
V: []byte("\x00\x00\x00\x00\x00\x00\x00\x00"),
})
buf []byte,
allowContainers, expectEOC bool,
recursionDepth int,
-) (item *Item, tail []byte, err error) {
+) (item Item, tail []byte, err error) {
if recursionDepth > ParseMaxRecursionDepth {
err = errors.New("deep recursion")
return
}
var off int
- item = &Item{}
item.T, item.V, off, err = atom.Decode(buf)
if err != nil {
return
err = atom.ErrUnknownType
return
}
- var sub *Item
- var v []*Item
+ var sub Item
+ var v []Item
for {
sub, buf, err = decode(buf, true, true, recursionDepth+1)
tail = buf
err = atom.ErrUnknownType
return
}
- v := make(map[string]*Item)
- var sub *Item
+ v := make(map[string]Item)
+ var sub Item
var keyPrev string
for {
sub, buf, err = decode(buf, false, true, recursionDepth+1)
return
}
chunkLen := int(item.V.(uint64))
- v := &Blob{ChunkLen: chunkLen}
- var sub *Item
+ v := Blob{ChunkLen: chunkLen}
+ var sub Item
BlobCycle:
for {
sub, buf, err = decode(buf, false, true, recursionDepth+1)
"go.cypherpunks.su/yac/gyac/types"
)
-func (item *Item) Encode(buf []byte) []byte {
+func (item Item) Encode(buf []byte) []byte {
switch item.T {
case types.NIL:
return atom.NILEncode(buf)
return atom.BigIntEncode(buf, item.V.(*big.Int))
case types.List:
buf = atom.ListEncode(buf)
- for _, v := range item.V.([]*Item) {
+ for _, v := range item.V.([]Item) {
buf = v.Encode(buf)
}
buf = atom.EOCEncode(buf)
case types.Map:
- m := item.V.(map[string]*Item)
+ m := item.V.(map[string]Item)
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
buf = atom.EOCEncode(buf)
case types.Blob:
- blob := item.V.(*Blob)
+ blob := item.V.(Blob)
buf = atom.BlobEncode(buf, blob.ChunkLen)
for _, chunk := range blob.Chunks {
if len(chunk) == blob.ChunkLen {
case types.Str:
return atom.StrEncode(buf, item.V.(string))
case types.Raw:
- return atom.RawEncode(buf, item.V.(*atom.Raw))
+ return atom.RawEncode(buf, item.V.(atom.Raw))
default:
panic("unhandled type")
}
return
}
-func FromGo(v any) *Item {
+func FromGo(v any) Item {
if v == nil {
- return &Item{T: types.NIL}
+ return Item{T: types.NIL}
}
rv := reflect.ValueOf(v)
if b, ok := v.([]byte); ok {
- return &Item{T: types.Bin, V: b}
+ return Item{T: types.Bin, V: b}
}
switch v := v.(type) {
case *Blob:
- return &Item{T: types.Blob, V: v}
+ return Item{T: types.Blob, V: *v}
+ case Blob:
+ return Item{T: types.Blob, V: v}
case time.Time:
t := tai64n.Leapsecs.Add(v)
var taiRaw []byte
tai.FromTime(t)
taiRaw = tai[:]
}
- return &Item{T: types.TAI64, V: taiRaw}
+ return Item{T: types.TAI64, V: taiRaw}
case *atom.Raw:
- return &Item{T: types.Raw, V: v}
+ return Item{T: types.Raw, V: *v}
+ case atom.Raw:
+ return Item{T: types.Raw, V: v}
case *big.Int:
- return &Item{T: types.BigInt, V: v}
+ return Item{T: types.BigInt, V: v}
}
switch reflect.TypeOf(v).Kind() {
case reflect.Pointer:
if rv.IsNil() {
- return &Item{T: types.NIL}
+ return Item{T: types.NIL}
}
return FromGo(rv.Elem().Interface())
case reflect.Slice:
- var ret []*Item
+ var ret []Item
if anys, ok := v.([]any); ok {
for _, v := range anys {
ret = append(ret, FromGo(v))
ret = append(ret, FromGo(rv.Index(i).Interface()))
}
}
- return &Item{T: types.List, V: ret}
+ return Item{T: types.List, V: ret}
case reflect.Map:
- ret := make(map[string]*Item, rv.Len())
+ ret := make(map[string]Item, rv.Len())
iter := rv.MapRange()
for iter.Next() {
ret[iter.Key().String()] = FromGo(iter.Value().Interface())
}
- return &Item{T: types.Map, V: ret}
+ return Item{T: types.Map, V: ret}
}
{
t := rv.Type()
if t.Kind() == reflect.Struct {
- ret := make(map[string]*Item)
+ ret := make(map[string]Item)
for _, f := range reflect.VisibleFields(t) {
fv := rv.FieldByIndex(f.Index)
name, omit := structTagRead(f)
case types.NIL:
empty = true
case types.List:
- if len(item.V.([]*Item)) == 0 {
+ if len(item.V.([]Item)) == 0 {
empty = true
}
case types.Map:
- if len(item.V.(map[string]*Item)) == 0 {
+ if len(item.V.(map[string]Item)) == 0 {
empty = true
}
}
ret[name] = item
}
}
- return &Item{T: types.Map, V: ret}
+ return Item{T: types.Map, V: ret}
}
}
switch v := v.(type) {
case bool:
- return &Item{T: types.Bool, V: v}
+ return Item{T: types.Bool, V: v}
case uuid.UUID:
- return &Item{T: types.UUID, V: v}
+ return Item{T: types.UUID, V: v}
case uint:
- return &Item{T: types.UInt, V: uint64(v)}
+ return Item{T: types.UInt, V: uint64(v)}
case uint8:
- return &Item{T: types.UInt, V: uint64(v)}
+ return Item{T: types.UInt, V: uint64(v)}
case uint16:
- return &Item{T: types.UInt, V: uint64(v)}
+ return Item{T: types.UInt, V: uint64(v)}
case uint32:
- return &Item{T: types.UInt, V: uint64(v)}
+ return Item{T: types.UInt, V: uint64(v)}
case uint64:
- return &Item{T: types.UInt, V: v}
+ return Item{T: types.UInt, V: v}
case int:
if v >= 0 {
- return &Item{T: types.UInt, V: uint64(v)}
+ return Item{T: types.UInt, V: uint64(v)}
}
- return &Item{T: types.Int, V: int64(v)}
+ return Item{T: types.Int, V: int64(v)}
case int8:
if v >= 0 {
- return &Item{T: types.UInt, V: uint64(v)}
+ return Item{T: types.UInt, V: uint64(v)}
}
- return &Item{T: types.Int, V: int64(v)}
+ return Item{T: types.Int, V: int64(v)}
case int16:
if v >= 0 {
- return &Item{T: types.UInt, V: uint64(v)}
+ return Item{T: types.UInt, V: uint64(v)}
}
- return &Item{T: types.Int, V: int64(v)}
+ return Item{T: types.Int, V: int64(v)}
case int32:
if v >= 0 {
- return &Item{T: types.UInt, V: uint64(v)}
+ return Item{T: types.UInt, V: uint64(v)}
}
- return &Item{T: types.Int, V: int64(v)}
+ return Item{T: types.Int, V: int64(v)}
case int64:
if v >= 0 {
- return &Item{T: types.UInt, V: uint64(v)}
+ return Item{T: types.UInt, V: uint64(v)}
}
- return &Item{T: types.Int, V: v}
+ return Item{T: types.Int, V: v}
case string:
- return &Item{T: types.Str, V: v}
+ return Item{T: types.Str, V: v}
default:
panic(fmt.Errorf("unhandled type: %+v", v))
}
)
func FuzzItemDecode(f *testing.F) {
- var item *Item
+ var item Item
var err error
var tail []byte
f.Fuzz(func(t *testing.T, b []byte) {
)
func Decode(dst any, raw []byte) (tail []byte, err error) {
- var item *gyac.Item
+ var item gyac.Item
item, tail, err = gyac.Decode(raw)
if err != nil {
return
"go.cypherpunks.su/yac/gyac/types"
)
-func (item *Item) ToGo() any {
+func (item Item) ToGo() any {
switch item.T {
case types.NIL:
return nil
return item.V.(int64)
case types.List:
var ret []any
- for _, v := range item.V.([]*Item) {
+ for _, v := range item.V.([]Item) {
ret = append(ret, v.ToGo())
}
return ret
case types.Map:
ret := make(map[string]any)
- for k, v := range item.V.(map[string]*Item) {
+ for k, v := range item.V.(map[string]Item) {
ret[k] = v.ToGo()
}
return ret
case types.Blob:
- return item.V.(*Blob)
+ return item.V.(Blob)
case types.BigInt:
return item.V.(*big.Int)
case types.Float:
tai := tai64n.TAI64(raw)
t, isLeap := tai64n.Leapsecs.Sub(tai.Time())
if isLeap {
- return &atom.Raw{T: atom.TAI64, V: raw}
+ return atom.Raw{T: atom.TAI64, V: raw}
}
return t
case tai64n.TAI64NSize:
tai := tai64n.TAI64N(raw)
t, isLeap := tai64n.Leapsecs.Sub(tai.Time())
if isLeap {
- return &atom.Raw{T: atom.TAI64N, V: raw}
+ return atom.Raw{T: atom.TAI64N, V: raw}
}
return t
case tai64n.TAI64NASize:
- return &atom.Raw{T: atom.TAI64NA, V: raw}
+ return atom.Raw{T: atom.TAI64NA, V: raw}
default:
panic("unexpected TAI size")
}
case types.Str:
return item.V.(string)
case types.Raw:
- return item.V.(*atom.Raw)
+ return item.V.(atom.Raw)
default:
panic(fmt.Errorf("unhandled type: %+v", item))
}
}
func SignedDataParse(data []byte) (sd *SignedData, tail []byte, err error) {
- var item *gyac.Item
+ var item gyac.Item
item, tail, err = gyac.Decode(data)
if err != nil {
return
return
}
-func SignedDataParseItem(item *gyac.Item) (sd *SignedData, err error) {
+func SignedDataParseItem(item gyac.Item) (sd *SignedData, err error) {
if item.T != types.Map {
err = errors.New("SignedDataParse: non-map")
return