diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-12-13 20:12:13 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-12-17 11:39:14 +0100 |
| commit | 8ef00507063baf3fa681bb53113cb33adda5e4d7 (patch) | |
| tree | 90f5be39889c5e064c92f16d9649627e84933820 /prog/encoding.go | |
| parent | eaeccee1d7f7a3f22e842309f21e3b118bd95254 (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.go | 40 |
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 { |
