/
serialize.go
96 lines (79 loc) · 2.82 KB
/
serialize.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package repo
import (
flatbuffers "github.com/google/flatbuffers/go"
"github.com/qri-io/qri/profile"
reporef "github.com/qri-io/qri/repo/ref"
repofb "github.com/qri-io/qri/repo/repo_fbs"
)
// RefList is a list of refs
type RefList []reporef.DatasetRef
// Len returns the length of refs. Used for sort.Interface
func (rs RefList) Len() int { return len(rs) }
// Less returns true if i comes before j. Used for sort.Interface
func (rs RefList) Less(i, j int) bool { return rs[i].Peername+rs[i].Name < rs[j].Peername+rs[j].Name }
// Swap flips the positions of i and j. Used for sort.Interface
func (rs RefList) Swap(i, j int) { rs[i], rs[j] = rs[j], rs[i] }
// FlatbufferBytes turns refs into a byte slice of flatbuffer data
func FlatbufferBytes(rs RefList) []byte {
builder := flatbuffers.NewBuilder(0)
count := len(rs)
offsets := make([]flatbuffers.UOffsetT, count)
for i, l := range rs {
offsets[i] = MarshalFlatbuffer(l, builder)
}
repofb.RepoStartRefsVector(builder, count)
for i := count - 1; i >= 0; i-- {
builder.PrependUOffsetT(offsets[i])
}
refsvo := builder.EndVector(count)
repofb.ReflistStart(builder)
repofb.ReflistAddRefs(builder, refsvo)
off := repofb.ReflistEnd(builder)
builder.Finish(off)
return builder.FinishedBytes()
}
// UnmarshalRefsFlatbuffer turns a repo flatbuffer into a list of refs
func UnmarshalRefsFlatbuffer(data []byte) (ls RefList, err error) {
repoFb := repofb.GetRootAsReflist(data, 0)
dec := &repofb.DatasetRef{}
ls = make(RefList, repoFb.RefsLength())
for i := 0; i < repoFb.RefsLength(); i++ {
repoFb.Refs(dec, i)
r, err := UnmarshalFlatbuffer(dec)
if err != nil {
return nil, err
}
ls[i] = r
}
return ls, nil
}
// MarshalFlatbuffer writes a ref to a builder
func MarshalFlatbuffer(r reporef.DatasetRef, builder *flatbuffers.Builder) flatbuffers.UOffsetT {
peername := builder.CreateString(r.Peername)
profileID := builder.CreateString(r.ProfileID.String())
name := builder.CreateString(r.Name)
path := builder.CreateString(r.Path)
fsiPath := builder.CreateString(r.FSIPath)
repofb.DatasetRefStart(builder)
repofb.DatasetRefAddPeername(builder, peername)
repofb.DatasetRefAddProfileID(builder, profileID)
repofb.DatasetRefAddName(builder, name)
repofb.DatasetRefAddPath(builder, path)
repofb.DatasetRefAddFsiPath(builder, fsiPath)
repofb.DatasetRefAddPublished(builder, r.Published)
return repofb.DatasetRefEnd(builder)
}
// UnmarshalFlatbuffer decodes a job from a flatbuffer
func UnmarshalFlatbuffer(rfb *repofb.DatasetRef) (r reporef.DatasetRef, err error) {
r = reporef.DatasetRef{
Peername: string(rfb.Peername()),
Name: string(rfb.Name()),
Path: string(rfb.Path()),
FSIPath: string(rfb.FsiPath()),
Published: rfb.Published(),
}
if pidstr := string(rfb.ProfileID()); pidstr != "" {
r.ProfileID, err = profile.IDB58Decode(pidstr)
}
return r, err
}