aboutsummaryrefslogtreecommitdiffstats
path: root/prog/encoding.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-12-13 20:12:13 +0100
committerDmitry Vyukov <dvyukov@google.com>2017-12-17 11:39:14 +0100
commit8ef00507063baf3fa681bb53113cb33adda5e4d7 (patch)
tree90f5be39889c5e064c92f16d9649627e84933820 /prog/encoding.go
parenteaeccee1d7f7a3f22e842309f21e3b118bd95254 (diff)
prog: don't serialize output data args
Fixes #188 We now will write just ""/1000 to denote a 1000-byte output buffer. Also we now don't store 1000-byte buffer in memory just to denote size. Old format is still parsed.
Diffstat (limited to 'prog/encoding.go')
-rw-r--r--prog/encoding.go40
1 files changed, 30 insertions, 10 deletions
diff --git a/prog/encoding.go b/prog/encoding.go
index 4d8150959..2b7999efc 100644
--- a/prog/encoding.go
+++ b/prog/encoding.go
@@ -74,15 +74,19 @@ func serialize(arg Arg, buf *bytes.Buffer, vars map[Arg]int, varSeq *int) {
fmt.Fprintf(buf, "&%v=", serializeAddr(arg))
serialize(a.Res, buf, vars, varSeq)
case *DataArg:
- data := a.Data
- if !arg.Type().Varlen() {
- // Statically typed data will be padded with 0s during
- // deserialization, so we can strip them here for readability.
- for len(data) >= 2 && data[len(data)-1] == 0 && data[len(data)-2] == 0 {
- data = data[:len(data)-1]
+ if a.Type().Dir() == DirOut {
+ fmt.Fprintf(buf, "\"\"/%v", a.Size())
+ } else {
+ data := a.Data()
+ if !arg.Type().Varlen() {
+ // Statically typed data will be padded with 0s during
+ // deserialization, so we can strip them here for readability.
+ for len(data) >= 2 && data[len(data)-1] == 0 && data[len(data)-2] == 0 {
+ data = data[:len(data)-1]
+ }
}
+ serializeData(buf, data)
}
- serializeData(buf, data)
case *GroupArg:
var delims []byte
switch arg.Type().(type) {
@@ -287,13 +291,29 @@ func (target *Target) parseArg(typ Type, p *parser, vars map[string]Arg) (Arg, e
if err != nil {
return nil, err
}
+ size := ^uint64(0)
+ if p.Char() == '/' {
+ p.Parse('/')
+ sizeStr := p.Ident()
+ size, err = strconv.ParseUint(sizeStr, 0, 64)
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse buffer size: %q", sizeStr)
+ }
+ }
if !typ.Varlen() {
- if diff := int(typ.Size()) - len(data); diff > 0 {
+ size = typ.Size()
+ } else if size == ^uint64(0) {
+ size = uint64(len(data))
+ }
+ if typ.Dir() == DirOut {
+ arg = MakeOutDataArg(typ, size)
+ } else {
+ if diff := int(size) - len(data); diff > 0 {
data = append(data, make([]byte, diff)...)
}
- data = data[:typ.Size()]
+ data = data[:size]
+ arg = MakeDataArg(typ, data)
}
- arg = MakeDataArg(typ, data)
case '{':
t1, ok := typ.(*StructType)
if !ok {