Flatbuffers を fbs-query をつかって読み込みは flatc の生成コードがつらみすぎるので自分でつくった でも書いたように だいたい動作している。
その後書き込みに関して実装していたのだけど、だいぶ動作するようになってきた。
//io io.Reader
q := query.Open(io)
q.Len()
q.Index().File().Id()
q.Index().File().Name()
q.Index().File().IndexAt()
書き込みはこうした
file := q.Index.File()
file.SetId(query.FromInt64(12))
file.SetName(query.FromString("hogehoge"))
以下のようにしたいところだけど
file.SetId(12)
コピーなしをサポートするためにこうなってます。まぁこのinterface はこの形もできるようにするかもしれないけど。
当然
root := query.Open(io)
file := query.NewFile()
file.SetId(query.FromInt64(12))
file.SetName(query.FromString("hogehoge"))
root.SetFile(file)
とかもできるようになってます。
書き込みのバッファは
type Base struct {
r io.Reader
bytes []byte
Diffs []Diff
}
type Diff struct {
Offset int
bytes []byte
}
こういう感じで構成されていて、読み込み時は Base.bytes にたまる。
書き込みを行うと、Diff.bytes にかいていく。
自分の主な用途だとうけとった fbs なデータを network で受け取り、 別の通信相手に書き換えて投げるという用途が多いため、 可能な限りコピーをなくして共有できる作りにした。
完全な単一のバッファだとやはりslice の問題とやはりバッファに挿入というのが かならずコピーが発生してしまうので、それをなくすことが理由。
ちなみに
root := query.Open(io)
file := root.Index().File()
file.SetId(query.FromInt64(12))
とかした場合には file には変更が反映されますが、 root にはされません。
なので Root() 関数を用意して message root を取り出せるようにしている。
root = file.Root()
root.Write(io)
まだtable のlist とかをサポートしてないとか 書き込み時にDiff とかで断片化してるのをまとめるとか (どうせwritev で送るんだけど) 終われば一段落。