Commit 8d794c02 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 7429c8ba
......@@ -404,9 +404,10 @@ func (p *AcceptIdentification) NEOEncodedLen() int {
size += 30
for i := 0; i < len(p.KnownMasterList); i++ {
a := &p.KnownMasterList[i]
size += 10 + len((*a).Address.Host)
}
return 0 + len(p.Primary.Host) + size
return 30 + len(p.Primary.Host) + size
}
func (p *AcceptIdentification) NEOEncode(data []byte) {
......@@ -726,9 +727,10 @@ func (p *AnswerPartitionTable) NEOEncodedLen() int {
size += 12
for i := 0; i < len(p.RowList); i++ {
a := &p.RowList[i]
size += 8 + len((*a).CellList)*8
}
return 0 + size
return 12 + size
}
func (p *AnswerPartitionTable) NEOEncode(data []byte) {
......@@ -816,9 +818,10 @@ func (p *NotifyPartitionTable) NEOEncodedLen() int {
size += 12
for i := 0; i < len(p.RowList); i++ {
a := &p.RowList[i]
size += 8 + len((*a).CellList)*8
}
return 0 + size
return 12 + size
}
func (p *NotifyPartitionTable) NEOEncode(data []byte) {
......@@ -2600,9 +2603,10 @@ func (p *AnswerPartitionList) NEOEncodedLen() int {
size += 12
for i := 0; i < len(p.RowList); i++ {
a := &p.RowList[i]
size += 8 + len((*a).CellList)*8
}
return 0 + size
return 12 + size
}
func (p *AnswerPartitionList) NEOEncode(data []byte) {
......@@ -2713,9 +2717,10 @@ func (p *AnswerNodeList) NEOEncodedLen() int {
size += 4
for i := 0; i < len(p.NodeList); i++ {
a := &p.NodeList[i]
size += 26 + len((*a).Address.Host)
}
return 0 + size
return 4 + size
}
func (p *AnswerNodeList) NEOEncode(data []byte) {
......@@ -2925,9 +2930,10 @@ func (p *NotifyNodeInformation) NEOEncodedLen() int {
size += 4
for i := 0; i < len(p.NodeList); i++ {
a := &p.NodeList[i]
size += 26 + len((*a).Address.Host)
}
return 0 + size
return 4 + size
}
func (p *NotifyNodeInformation) NEOEncode(data []byte) {
......
......@@ -210,8 +210,8 @@ func (b *Buffer) emit(format string, a ...interface{}) {
// interface of codegenerator for coder/decoder
type CodecCodeGen interface {
genPrologue(recvName, typeName string)
genEpilogue()
// tell codegen it should generate code for top-level function
setFunc(recvName, typeName string)
// emit code to process basic fixed types (not string)
// userType is type actually used in source (for which typ is underlying), or nil
......@@ -223,44 +223,68 @@ type CodecCodeGen interface {
// XXX particular case of slice
genStrBytes(path string)
// get generated code.
// for top-level functions this is whole function including return and closing }
// for not function this is generated code needed for resultExpr()
generatedCode() string
// get result expression
// this is result of computations for not top-level code XXX
resultExpr() string
}
// sizer/encode/decode codegen
type coderForFunc struct {
recvName string // receiver/type for top-level func
typeName string // or empty
}
func (c *coderForFunc) setFunc(recvName, typeName string) {
c.recvName = recvName
c.typeName = typeName
}
type sizer struct {
Buffer // XXX
n int
symLenv []string // symbolic lengths to add to size
Buffer // buffer for code
n int // fixed part of size
symLenv []string // symbolic part of size
varN int // suffix to add to variables (size0, size1, ...) - for nested computations
varSizeUsed bool // whether var size was used
recvName string // receiver/type for top-level func
typeName string // or empty
coderForFunc
}
// get variable name for varname
func (s *sizer) var_(varname string) string {
return fmt.Sprintf("%s%d", varname, s.varN)
}
// create new sizer for subsize calculation (e.g. for loop)
func (s *sizer) subSizer() *sizer {
return &sizer{varN: s.varN + 1}
}
type encoder struct {
Buffer // XXX
n int
coderForFunc
}
type decoder struct {
Buffer // buffer for generated code
n int // current decode position in data
coderForFunc
}
var _ CodecCodeGen = (*sizer)(nil)
var _ CodecCodeGen = (*encoder)(nil)
var _ CodecCodeGen = (*decoder)(nil)
func (s *sizer) generatedCode() string {
prologue := Buffer{}
if s.recvName != "" {
prologue.emit("func (%s *%s) NEOEncodedLen() int {", s.recvName, s.typeName)
}
if s.varSizeUsed {
prologue.emit("var size int")
}
epilogue := Buffer{}
func (s *sizer) resultExpr() string {
size := fmt.Sprintf("%v", s.n)
if len(s.symLenv) > 0 {
size += " + " + strings.Join(s.symLenv, " + ")
......@@ -268,61 +292,74 @@ func (s *sizer) generatedCode() string {
if s.varSizeUsed {
size += " + size"
}
epilogue.emit("return %v", size)
epilogue.emit("}\n")
return prologue.String() + s.String() + epilogue.String() // XXX -> d.buf.String() ?
return size
}
func (e *encoder) generatedCode() string {
return e.String() // XXX -> d.buf.String() ?
}
func (s *sizer) generatedCode() string {
code := Buffer{}
// prologue
if s.recvName != "" {
code.emit("func (%s *%s) NEOEncodedLen() int {", s.recvName, s.typeName)
}
if s.varSizeUsed {
code.emit("var size int")
}
func (d *decoder) generatedCode() string {
return d.String() // XXX -> d.buf.String() ?
}
code.Write(s.Bytes()) // XXX -> s.buf.Bytes() ?
func (s *sizer) genPrologue(recvName, typeName string) {
s.recvName = recvName
s.typeName = typeName
//s.emit("func (%s *%s) NEOEncodedLen() int {", recvName, typeName)
}
// epilogue
if s.recvName != "" {
code.emit("return %v", s.resultExpr())
code.emit("}\n")
}
func (e *encoder) genPrologue(recvName, typeName string) {
e.emit("func (%s *%s) NEOEncode(data []byte) {", recvName, typeName)
return code.String()
}
func (d *decoder) genPrologue(recvName, typeName string) {
d.emit("func (%s *%s) NEODecode(data []byte) (int, error) {", recvName, typeName)
d.emit("var nread uint32")
func (e *encoder) resultExpr() string {
panic("should not be called (?)")
}
func (s *sizer) genEpilogue() {
/*
size := fmt.Sprintf("%v", s.n)
if len(s.symLenv) > 0 {
size += " + " + strings.Join(s.symLenv, " + ")
}
if s.varSizeUsed {
size += " + size"
func (e *encoder) generatedCode() string {
code := Buffer{}
// prologue
if e.recvName != "" {
code.emit("func (%s *%s) NEOEncode(data []byte) {", e.recvName, e.typeName)
}
s.emit("return %v", size)
s.emit("}\n")
*/
code.Write(e.Bytes()) // XXX -> e.buf.Bytes() ?
// epilogue
code.emit("}\n")
return code.String()
}
func (e *encoder) genEpilogue() {
e.emit("}\n")
func (d *decoder) resultExpr() string {
panic("should not be called (?)")
}
func (d *decoder) genEpilogue() {
d.emit("return int(nread) + %v, nil", d.n)
d.emit("\noverflow:")
d.emit("return 0, ErrDecodeOverflow")
d.emit("goto overflow") // TODO check if overflow used at all and remove
d.emit("}\n")
func (d *decoder) generatedCode() string {
code := Buffer{}
// prologue
if d.recvName != "" {
code.emit("func (%s *%s) NEODecode(data []byte) (int, error) {", d.recvName, d.typeName)
}
code.emit("var nread uint32")
code.Write(d.Bytes()) // XXX -> d.buf.Bytes() ?
// epilogue
code.emit("return int(nread) + %v, nil", d.n)
code.emit("\noverflow:")
code.emit("return 0, ErrDecodeOverflow")
code.emit("goto overflow") // TODO check if overflow used at all and remove
code.emit("}\n")
return code.String()
}
func (s *sizer) genBasic(path string, typ *types.Basic, userType types.Type) {
basic := basicTypes[typ.Kind()]
s.n += basic.wireSize
......@@ -365,7 +402,6 @@ func (d *decoder) genBasic(assignto string, typ *types.Basic, userType types.Typ
func (s *sizer) genStrBytes(path string) {
s.n += 4
s.symLenv = append(s.symLenv, fmt.Sprintf("len(%s)", path))
//s.n = 0
}
func (e *encoder) genStrBytes(path string) {
......@@ -407,16 +443,15 @@ func (s *sizer) genSlice(path string, typ *types.Slice, obj types.Object) {
s.varSizeUsed = true
s.n += 4
s.emit("size += %v", s.n)
s.n = 0
s.emit("for i := 0; i < len(%v); i++ {", path)
s.emit("a := &%s[i]", path)
//codegenType("(*a)", typ.Elem(), obj, s)
sloop := &sizer{}
sloop := s.subSizer()
codegenType("(*a)", typ.Elem(), obj, sloop)
// FIXME vvv if symLenv is ø; -> turn into "result" function
s.emit("size += %v + %v", sloop.n, strings.Join(sloop.symLenv, " + "))
s.emit(sloop.generatedCode())
s.emit("size += %v", sloop.resultExpr())
s.emit("}")
s.n = 0
}
func (e *encoder) genSlice(path string, typ *types.Slice, obj types.Object) {
......@@ -470,8 +505,10 @@ func (s *sizer) genMap(path string, typ *types.Map, obj types.Object) {
return
}
panic("UNTESTED")
s.varSizeUsed = true
s.emit("size += %v + 4", s.n)
s.n += 4
s.emit("size += %v", s.n)
s.n = 0
s.emit("for key := range %s {", path)
codegenType("key", typ.Key(), obj, s)
......@@ -591,7 +628,7 @@ func codegenType(path string, typ types.Type, obj types.Object, codegen CodecCod
// generate encoder/decode funcs for a type declaration typespec
func generateCodecCode(typespec *ast.TypeSpec, codec CodecCodeGen) string {
codec.genPrologue("p", typespec.Name.Name)
codec.setFunc("p", typespec.Name.Name)
// type & object which refers to this type
typ := info.Types[typespec.Type].Type
......@@ -599,6 +636,5 @@ func generateCodecCode(typespec *ast.TypeSpec, codec CodecCodeGen) string {
codegenType("p", typ, obj, codec)
codec.genEpilogue()
return codec.generatedCode()
}
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