| {#--- Begin #} |
| function {{struct.name}}(values) { |
| this.initDefaults_(); |
| this.initFields_(values); |
| } |
| |
| {#--- Enums #} |
| {%- from "enum_definition.tmpl" import enum_def %} |
| {% for enum in struct.enums %} |
| {{enum_def("%s.%s"|format(struct.name, enum.name), enum)}} |
| {%- endfor %} |
| |
| {#--- Constants #} |
| {% for constant in struct.constants %} |
| {{struct.name}}.{{constant.name}} = {{constant.value|expression_to_text}}; |
| {%- endfor %} |
| |
| {#--- initDefaults() #} |
| {{struct.name}}.prototype.initDefaults_ = function() { |
| {%- for packed_field in struct.packed.packed_fields %} |
| this.{{packed_field.field.name}} = {{packed_field.field|default_value}}; |
| {%- endfor %} |
| }; |
| |
| {#--- initFields() #} |
| {{struct.name}}.prototype.initFields_ = function(fields) { |
| for(var field in fields) { |
| if (this.hasOwnProperty(field)) |
| this[field] = fields[field]; |
| } |
| }; |
| |
| {#--- Validation #} |
| |
| {{struct.name}}.validate = function(messageValidator, offset) { |
| var err; |
| err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); |
| if (err !== validator.validationError.NONE) |
| return err; |
| |
| var kVersionSizes = [ |
| {%- for version in struct.versions %} |
| {version: {{version.version}}, numBytes: {{version.num_bytes}}}{% if not loop.last %}, |
| {%- endif -%} |
| {% endfor %} |
| ]; |
| err = messageValidator.validateStructVersion(offset, kVersionSizes); |
| if (err !== validator.validationError.NONE) |
| return err; |
| |
| {#- Before validating fields introduced at a certain version, we need to add |
| a version check, which makes sure we skip further validation if |object| |
| is from an earlier version. |last_checked_version| records the last |
| version that we have added such version check. #} |
| {%- from "validation_macros.tmpl" import validate_struct_field %} |
| {%- set last_checked_version = 0 %} |
| {%- for packed_field in struct.packed.packed_fields_in_ordinal_order %} |
| {%- set offset = packed_field|field_offset %} |
| {%- set field = packed_field.field %} |
| {%- set name = struct.name ~ '.' ~ field.name %} |
| {% if field|is_object_field or field|is_any_handle_or_interface_field or |
| field|is_enum_field %} |
| {% if packed_field.min_version > last_checked_version %} |
| {% set last_checked_version = packed_field.min_version %} |
| // version check {{name}} |
| if (!messageValidator.isFieldInStructVersion(offset, {{packed_field.min_version}})) |
| return validator.validationError.NONE; |
| {%- endif -%} |
| {{validate_struct_field(field, offset, name)|indent(4)}} |
| {%- endif %} |
| {%- endfor %} |
| |
| return validator.validationError.NONE; |
| }; |
| |
| {#--- Encoding and decoding #} |
| |
| {{struct.name}}.encodedSize = codec.kStructHeaderSize + {{struct.packed|payload_size}}; |
| |
| {{struct.name}}.decode = function(decoder) { |
| var packed; |
| var val = new {{struct.name}}(); |
| var numberOfBytes = decoder.readUint32(); |
| var version = decoder.readUint32(); |
| {%- for byte in struct.bytes %} |
| {%- if byte.packed_fields|length >= 1 and |
| byte.packed_fields[0].field|is_bool_field %} |
| packed = decoder.readUint8(); |
| {%- for packed_field in byte.packed_fields %} |
| val.{{packed_field.field.name}} = (packed >> {{packed_field.bit}}) & 1 ? true : false; |
| {%- endfor %} |
| {%- else %} |
| {%- for packed_field in byte.packed_fields %} |
| val.{{packed_field.field.name}} = decoder.{{packed_field.field.kind|decode_snippet}}; |
| {%- endfor %} |
| {%- endif %} |
| {%- if byte.is_padding %} |
| decoder.skip(1); |
| {%- endif %} |
| {%- endfor %} |
| return val; |
| }; |
| |
| {{struct.name}}.encode = function(encoder, val) { |
| var packed; |
| encoder.writeUint32({{struct.name}}.encodedSize); |
| encoder.writeUint32({{struct.versions[-1].version}}); |
| |
| {%- for byte in struct.bytes %} |
| {%- if byte.packed_fields|length >= 1 and |
| byte.packed_fields[0].field|is_bool_field %} |
| packed = 0; |
| {%- for packed_field in byte.packed_fields %} |
| packed |= (val.{{packed_field.field.name}} & 1) << {{packed_field.bit}} |
| {%- endfor %} |
| encoder.writeUint8(packed); |
| {%- else %} |
| {%- for packed_field in byte.packed_fields %} |
| encoder.{{packed_field.field.kind|encode_snippet}}val.{{packed_field.field.name}}); |
| {%- endfor %} |
| {%- endif %} |
| {%- if byte.is_padding %} |
| encoder.skip(1); |
| {%- endif %} |
| {%- endfor %} |
| }; |