Commit 51d087af authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 035449f9
......@@ -595,7 +595,7 @@ type StoreObject struct {
Serial zodb.Tid
Compression bool
Checksum Checksum
Data []byte // TODO separately (for writev)
Data []byte // TODO encode -> separately (for writev)
DataSerial zodb.Tid
Tid zodb.Tid
}
......@@ -646,8 +646,8 @@ type AnswerObject struct {
NextSerial zodb.Tid // XXX but there it is out of sync
Compression bool
Checksum Checksum
// Data []byte // TODO separately (for writev)
Data *zodb.Buf
// Data []byte // TODO encode -> separately (for writev)
Data *zodb.Buf // TODO encode -> separately (for writev)
DataSerial zodb.Tid
}
......
......@@ -116,8 +116,8 @@ func typeName(typ types.Type) string {
return types.TypeString(typ, qf)
}
// type of neo.customCodec
var neo_customCodec *types.Interface
var neo_customCodec *types.Interface // type of neo.customCodec
var zodbBuf types.Type // type of zodb.Buf
// bytes.Buffer + bell & whistles
type Buffer struct {
......@@ -243,7 +243,7 @@ func main() {
log.SetFlags(0)
// go through proto.go and AST'ify & typecheck it
zodbPkg = loadPkg("lab.nexedi.com/kirr/neo/go/zodb", "../zodb/zodb.go")
zodbPkg = loadPkg("lab.nexedi.com/kirr/neo/go/zodb", "../zodb/zodb.go", "../zodb/buffer.go")
neoPkg = loadPkg("lab.nexedi.com/kirr/neo/go/neo", "proto.go", "packed.go")
// extract neo.customCodec
......@@ -257,6 +257,13 @@ func main() {
log.Fatal("customCodec is not interface (got %v)", cc.Type())
}
// extract zodb.Buf
__ := zodbPkg.Scope().Lookup("Buf")
if __ == nil {
log.Fatal("cannot find `zodb.Buf`")
}
zodbBuf = __.Type()
// prologue
f := fileMap["proto.go"]
buf := Buffer{}
......@@ -455,6 +462,9 @@ type CodeGenerator interface {
genArray1(path string, typ *types.Array)
genSlice1(path string, typ types.Type)
// zodb.Buf
genBuf(path string)
// generate code for a custom type which implements its own
// encoding/decoding via implementing neo.customCodec interface.
genCustom(path string)
......@@ -913,6 +923,33 @@ func (d *decoder) genSlice1(assignto string, typ types.Type) {
d.emit("}")
}
// emit code to size/encode/decode zodb.Buf
// same as slice1 but buffer is allocated via zodb.BufAlloc
func (s *sizer) genBuf(path string) {
s.genSlice1(path + ".Data", nil) // XXX typ unused
}
func (e *encoder) genBuf(path string) {
e.genSlice1(path + ".Data", nil) // XXX typ unused
}
func (d *decoder) genBuf(path string) {
d.emit("{")
d.genBasic("l:", types.Typ[types.Uint32], nil)
d.resetPos()
d.overflowCheck()
d.overflow.AddExpr("l")
// TODO eventually do not copy but reference original
d.emit("%v= zodb.BufAlloc(l)", path)
d.emit("copy(%v.Data, data[:l])", path)
d.emit("data = data[l:]")
d.emit("}")
}
// emit code to size/encode/decode slice
// len u32
// [len]item
......@@ -1120,12 +1157,19 @@ func (d *decoder) genCustom(path string) {
// obj is object that uses this type in source program (so in case of an error
// we can point to source location for where it happened)
func codegenType(path string, typ types.Type, obj types.Object, codegen CodeGenerator) {
// neo.customCodec
if types.Implements(typ, neo_customCodec) ||
types.Implements(types.NewPointer(typ), neo_customCodec) {
codegen.genCustom(path)
return
}
// zodb.Buf
if tptr, ok := typ.Underlying().(*types.Pointer); ok && tptr.Elem() == zodbBuf {
codegen.genBuf(path)
return
}
switch u := typ.Underlying().(type) {
case *types.Basic:
// go puts string into basic, but it is really slice1
......@@ -1167,6 +1211,8 @@ func codegenType(path string, typ types.Type, obj types.Object, codegen CodeGene
case *types.Map:
codegen.genMap(path, u, obj)
case *types.Pointer:
default:
log.Fatalf("%v: %v has unsupported type %v (%v)", pos(obj),
obj.Name(), typ, u)
......
......@@ -1930,7 +1930,7 @@ func (*AnswerObject) neoMsgCode() uint16 {
}
func (p *AnswerObject) neoMsgEncodedLen() int {
return 57 + len(p.Data)
return 57 + len(p.Data.Data)
}
func (p *AnswerObject) neoMsgEncode(data []byte) {
......@@ -1940,10 +1940,10 @@ func (p *AnswerObject) neoMsgEncode(data []byte) {
(data[24:])[0] = bool2byte(p.Compression)
copy(data[25:], p.Checksum[:])
{
l := uint32(len(p.Data))
l := uint32(len(p.Data.Data))
binary.BigEndian.PutUint32(data[45:], l)
data = data[49:]
copy(data, p.Data)
copy(data, p.Data.Data)
data = data[l:]
}
binary.BigEndian.PutUint64(data[0:], uint64(p.DataSerial))
......@@ -1966,8 +1966,8 @@ func (p *AnswerObject) neoMsgDecode(data []byte) (int, error) {
goto overflow
}
nread += 8 + l
p.Data = make([]byte, l)
copy(p.Data, data[:l])
p.Data = zodb.BufAlloc(l)
copy(p.Data.Data, data[:l])
data = data[l:]
}
p.DataSerial = zodb.Tid(binary.BigEndian.Uint64(data[0:]))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment