Flatbuffersfbs-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 で送るんだけど) 終われば一段落。