| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| {% import "encoding_macros.tmpl" as encoding_macros %} |
| |
| {% macro define(struct, exported=True) %} |
| type {{struct|name(exported)}} struct { |
| {% for field in struct.fields %} |
| {{field|name(exported)}} {{field.kind|go_type}} |
| {% endfor %} |
| } |
| |
| func (s *{{struct|name(exported)}}) Encode(encoder *bindings.Encoder) error { |
| {% set HEADER_SIZE = 8 %} |
| encoder.StartStruct({{struct.versions[-1].num_bytes - HEADER_SIZE}}, {{struct.versions[-1].version}}) |
| {% for byte in struct.bytes %} |
| {% for packed_field in byte.packed_fields %} |
| {{encoding_macros.encode('s.'~packed_field.field|name(exported), packed_field.field.kind)|tab_indent()}} |
| {% endfor %} |
| {% endfor %} |
| if err := encoder.Finish(); err != nil { |
| return err |
| } |
| return nil |
| } |
| |
| var {{struct|name(False)}}_Versions []bindings.DataHeader = []bindings.DataHeader{ |
| {% for versionInfo in struct.versions %} |
| bindings.DataHeader{{'{'}}{{versionInfo.num_bytes}}, {{versionInfo.version}}{{'}'}}, |
| {% endfor %} |
| } |
| |
| func (s *{{struct|name(exported)}}) Decode(decoder *bindings.Decoder) error { |
| header, err := decoder.StartStruct() |
| if err != nil { |
| return err |
| } |
| index := sort.Search(len({{struct|name(False)}}_Versions), func(i int) bool { |
| return {{struct|name(False)}}_Versions[i].ElementsOrVersion >= header.ElementsOrVersion |
| }) |
| if index < len({{struct|name(False)}}_Versions) { |
| if {{struct|name(False)}}_Versions[index].ElementsOrVersion > header.ElementsOrVersion { |
| index-- |
| } |
| expectedSize := {{struct|name(False)}}_Versions[index].Size |
| if expectedSize != header.Size { |
| return &bindings.ValidationError{bindings.UnexpectedStructHeader, |
| fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size), |
| } |
| } |
| } |
| {% for byte in struct.bytes %} |
| {% for packed_field in byte.packed_fields %} |
| if header.ElementsOrVersion >= {{packed_field.min_version}} { |
| {{encoding_macros.decode('s.'~packed_field.field|name(exported), packed_field.field.kind)|tab_indent(2)}} |
| } |
| {% endfor %} |
| {% endfor %} |
| if err := decoder.Finish(); err != nil { |
| return err |
| } |
| return nil |
| } |
| |
| {% endmacro %} |