blob: 444ffdb26e4cb0eb0b24f02fa4f93e0beb5cf418 [file] [log] [blame]
// 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 %}