19edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer# Copyright 2015 The Chromium OS Authors. All rights reserved.
29edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer# Use of this source code is governed by a BSD-style license that can be
39edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer# found in the LICENSE file.
49edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
59edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""A code generator for TPM 2.0 structures.
69edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
7595736f2120e594839d6e73cb8245d8d7e5c2360Vadim BendeburyThe structure generator provides classes to create various objects
8595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury(structures, unions, constants, etc.) and then convert the set of generated
9595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendeburyobjects into valid C files named tpm_generated.{h,c}.
10595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
119edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
129edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
139edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developerfrom __future__ import print_function
149edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
15595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendeburyimport datetime
169edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developerimport re
179edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
18595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendeburyfrom subprocess import call
199edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
209edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer_BASIC_TYPES = ['uint8_t', 'int8_t', 'uint16_t', 'int16_t', 'uint32_t',
219edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer                'int32_t', 'uint64_t', 'int64_t']
229edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer_OUTPUT_FILE_H = 'tpm_generated.h'
239edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer_OUTPUT_FILE_CC = 'tpm_generated.c'
24595736f2120e594839d6e73cb8245d8d7e5c2360Vadim BendeburyCOPYRIGHT_HEADER = (
25595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    '// Copyright %d The Chromium OS Authors. All rights reserved.\n'
269edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    '// Use of this source code is governed by a BSD-style license that can '
279edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    'be\n'
289edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    '// found in the LICENSE file.\n'
299edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    '\n'
30595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    '// THIS CODE IS GENERATED - DO NOT MODIFY!\n' %
31595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    datetime.datetime.now().year)
32595736f2120e594839d6e73cb8245d8d7e5c2360Vadim BendeburyHEADER_FILE_GUARD_HEADER = """
339edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer#ifndef %(name)s
349edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer#define %(name)s
359edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
36595736f2120e594839d6e73cb8245d8d7e5c2360Vadim BendeburyHEADER_FILE_GUARD_FOOTER = """
379edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer#endif  // %(name)s
389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
399edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer_HEADER_FILE_INCLUDES = """
409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer#include <endian.h>
419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer#include <string.h>
429edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
439edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer#include "TPM_Types.h"
449edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer#include "Tpm.h"
459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
469edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer_IMPLEMENTATION_FILE_INCLUDES = """
479edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer#include "tpm_generated.h"
489edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
499edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer# Function signatures for generated marshaling code are specified in TCG TPM2.0
509edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer# Library Specification, Part 4: Supporting Routines, sections 4.2.2 and 4.2.3.
519edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer_MARSHAL_BASIC_TYPE = """
529edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperUINT16 %(type)s_Marshal(%(type)s *source, BYTE **buffer, INT32 *size) {
53fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  %(type)s value_net = *source;
549edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (!size || *size < sizeof(%(type)s)) {
5569289285089a481cf80d1de423811fb0d903c9f6Vadim Bendebury    return 0;  // Nothing has been marshaled.
569edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }
579edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  switch (sizeof(%(type)s)) {
589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    case 2:
599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      value_net = htobe16(*source);
609edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      break;
619edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    case 4:
629edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      value_net = htobe32(*source);
639edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      break;
649edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    case 8:
659edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      value_net = htobe64(*source);
669edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      break;
679edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    default:
689edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      break;
699edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }
709edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  memcpy(*buffer, &value_net, sizeof(%(type)s));
719edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  *buffer += sizeof(%(type)s);
729edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  *size -= sizeof(%(type)s);
739edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  return sizeof(%(type)s);
749edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer}
759edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
769edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperTPM_RC %(type)s_Unmarshal(%(type)s *target, BYTE **buffer, INT32 *size) {
77fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  %(type)s value_net = 0;
789edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (!size || *size < sizeof(%(type)s)) {
799edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return TPM_RC_INSUFFICIENT;
809edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }
819edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  memcpy(&value_net, *buffer, sizeof(%(type)s));
829edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  switch (sizeof(%(type)s)) {
839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    case 2:
849edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      *target = be16toh(value_net);
859edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      break;
869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    case 4:
879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      *target = be32toh(value_net);
889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      break;
899edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    case 8:
909edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      *target = be64toh(value_net);
919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      break;
929edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    default:
939edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      *target = value_net;
949edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }
959edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  *buffer += sizeof(%(type)s);
969edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  *size -= sizeof(%(type)s);
979edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  return TPM_RC_SUCCESS;
989edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer}
999edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
1009edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer_STANDARD_MARSHAL_DECLARATION = """
1019edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperUINT16 %(type)s_Marshal(
1029edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(type)s *source,
1039edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
1049edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size);
1059edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
1069edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperTPM_RC %(type)s_Unmarshal(
1079edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(type)s *target,
1089edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
1099edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size);
1109edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
1119edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
112595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
113595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendeburydef _IsTPM2B(name):
1149edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  return name.startswith('TPM2B_')
1159edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
1169edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
117595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendeburyclass Field(object):
118595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  """Represents a field in TPM structure or union.
119595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
120595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  This object is used in several not fully overlapping cases, not all
121595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  attributes apply to all use cases.
122595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
123595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  The 'array_size' and 'run_time_size' attributes below are related to the
124595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  following code example:
125595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
126595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  struct {
127595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    int size;
128595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    byte array[MAX_SIZE]
129595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  } object.
130595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
131595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  In this structure the actual number of bytes in the array could be anything
132595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  from zero to MAX_SIZE. The field 'size' denotes the actual number of
133595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  elements at run time. So, when this object is constructed, array_size is
134595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  'MAX_SIZE' and run_time_size is 'size'.
135595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
136595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  The 'selector_value' attribute is used to associate union fields with
137595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  certain object types. For instance
138595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
139595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  typedef union {
140595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    TPM2B_PUBLIC_KEY_RSA  rsa;
141595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    TPMS_ECC_POINT        ecc;
142595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  } TPMU_PUBLIC_ID;
143595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
144595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  the field named 'rsa' will have its 'selector_value' set to 'TPM_ALG_RSA'.
145595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
146595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  Attributes:
147595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    field_type: a string, the type of field.
148595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    field_name: a string, the name of the field.
149595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    array_size: a string, see example above
150595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    run_time_size: a string, see example above
151595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    selector_value: a string, see example above
152595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    conditional_value: a string, necessary for validation when unmarshaling.
153595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                       Some types have a value that is allowed for some
154595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                       commands but not others. E.g. 'TPM_RS_PW' is a
155595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                       conditional value for the 'TPMI_SH_AUTH_SESSION' type
156595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                       and TPM_ALG_NULL is a conditional value for the
157595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                       TPMI_ALG_HASH type.
158595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  """
159595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  _MARSHAL_FIELD_ARRAY = """
160595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  for (i = 0; i < source->%(array_length)s; ++i) {
161595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    total_size += %(type)s_Marshal(&source->%(name)s[i], buffer, size);
162595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  }"""
163595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  _UNMARSHAL_FIELD_ARRAY = """
164595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  for (i = 0; i < target->%(array_length)s; ++i) {
165595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    result = %(type)s_Unmarshal(&target->%(name)s[i], buffer, size);
166595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    if (result != TPM_RC_SUCCESS) {
167595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      return result;
168595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    }
169595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  }"""
170595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
171595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  def __init__(self, field_type, field_name,
172595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury               selector=None, array_size='',
173595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury               conditional_value='FALSE',
174595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury               run_time_size=None):
175595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    """Initializes a Field instance.
176595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
177595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    Args:
178595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field_type: Initial value for the field type attribute.
179595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field_name: Initial value for the field name attribute.
180595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      selector: Initial value for the selector attribute.
181595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      array_size: Initial value for the array_size attribute.
182595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      conditional_value: Initial value of the conditional_value attribute.
183595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      run_time_size: Initial value of the run_time_size attribute
184595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    """
185595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    if not field_type:
186595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # Some tables include rows without data type, for instance 'Table 70 -
187595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # Definition of TPMU_HA Union' in part 2. These rows are supposed to
188595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # cause another case added to the switch in the marshaling function
189595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # (processing of TPM_ALG_NULL in this example). Setting field name to ''
190595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # makes sure that the actual generated structure/union does not have an
191595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # entry for this field, setting type of such field to some value
192595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # simplifies functions generating the marshaling code.
193595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      self.field_type = 'BYTE'
194595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      self.field_name = ''
195595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    else:
196595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      self.field_type = field_type
197595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      self.field_name = field_name
198595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    self.array_size = array_size
199595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    self.selector_value = selector
200595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    self.conditional_value = conditional_value
201595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    self.run_time_size = run_time_size
202595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
203595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  def OutputMarshal(self, out_file, typemap):
204595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    """Write a call to marshal the field this instance represents.
205595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
206595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    Args:
207595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      out_file: The output file.
208595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      typemap: A dict mapping type names to the corresponding object.
209595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    """
210595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    if self.array_size:
211595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      if self.run_time_size:
212595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        real_size = self.run_time_size
213595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      else:
214595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        real_size = self.array_size
215595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      out_file.write(
216595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury          self._MARSHAL_FIELD_ARRAY % {'type': self.field_type,
217595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                                       'name': self.field_name,
218595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                                       'array_length': real_size})
219595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    else:
220595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      typemap[self.field_type].OutputMarshalCall(out_file, self)
221595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
222595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  def OutputUnmarshal(self, out_file, typemap):
223595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    """Write a call to unmarshal the field this instance represents.
224595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
225595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    Args:
226595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      out_file: The output file.
227595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      typemap: A dict mapping type names to the corresponding object.
228595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    """
229595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    if self.array_size:
230595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      if self.run_time_size:
231595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        real_size = self.run_time_size
232595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      else:
233595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        real_size = self.array_size
234595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      out_file.write(
235595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury          self._UNMARSHAL_FIELD_ARRAY % {'type': self.field_type,
236595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                                         'name': self.field_name,
237595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                                         'array_length': real_size})
238595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    else:
239595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      typemap[self.field_type].OutputUnmarshalCall(out_file, self)
240595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
241595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
2429edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developerclass TPMType(object):
243595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  """Base type for all TPMTypes.
2449edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
2459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     Contains functions and string literals common to all TPM types.
246f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury
247f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury     Attributes:
248f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury      _base_type: a string, when set - the very basic type this type is
249f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury                  derived from (should be used for marshaling/unmarshaling to
250f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury                  shortcut multiple nested invocations).
2519edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """
2529edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # A function to marshal a TPM typedef.
2539edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _TYPEDEF_MARSHAL_FUNCTION = """
2549edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperUINT16 %(new_type)s_Marshal(
2559edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(new_type)s *source,
2569edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
2579edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size) {
2589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  return %(old_type)s_Marshal(source, buffer, size);
2599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer}
2609edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
2619edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # The function signature and unmarshaling call to the base type of a TPM
2629edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # typedef. After the value is unmarshaled, additional validation code is
2639edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # generated based on tables in TCG TPM2.0 Library Specification, Part 2:
2649edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # Structures.
2659edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _TYPEDEF_UNMARSHAL_START = """
2669edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperTPM_RC %(new_type)s_Unmarshal(
2679edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(new_type)s *target,
2689edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
2699edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size) {
2709edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  TPM_RC result;
2719edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  result = %(old_type)s_Unmarshal(target, buffer, size);
2729edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (result != TPM_RC_SUCCESS) {
2739edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return result;
2749edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
2759edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _UNMARSHAL_END = '\n  return TPM_RC_SUCCESS;\n}\n'
2769edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # Snippets of code for value validation.
2779edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _VALUE_START_SWITCH = '\n  switch (%(name)s) {'
2789edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _VALUE_CASE = '\n    case %(value)s:'
2799edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _VALUE_CASE_IFDEF = '\n#ifdef %(value)s\n    case %(value)s:\n#endif'
2809edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _VALUE_END_SWITCH = """
2819edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      break;
2829edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    default:
2839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return %(error_code)s;
2849edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
2859edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # A declaration for marshaling and unmarshaling functions for a TPM type.
2869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _MARSHAL_DECLARATION = _STANDARD_MARSHAL_DECLARATION
2879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # Snippets of code which make calls to marshaling functions. Marshals a value
2889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # of type 'type' into a field 'name' within a structure. This is used in
2899edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # generation of structure and command marshaling code.
2909edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _MARSHAL_CALL = """
2919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  total_size += %(type)s_Marshal(
2929edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      &source->%(name)s, buffer, size);"""
2939edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _UNMARSHAL_CALL = """
2949edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  result = %(type)s_Unmarshal(
2959edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      &target->%(name)s, buffer, size);
2969edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (result != TPM_RC_SUCCESS) {
2979edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return result;
2989edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
2999edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
300f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury  def __init__(self):
301f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    self._base_type = None
302f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury
303f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury  def SetBaseType(self, base_type):
304f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    self._base_type = base_type
305f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury
306f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury  def _GetBaseType(self, out_file, marshalled_types, typemap):
307f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    '''Return base type for this object.
308f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury
309f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    The base type is used for shortcutting marshaling/unmarshaling code.
310f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury
311f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    If _base_type is not set, return the old_type value as the base type.
312f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury
313f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    If the base type's marshaling/unmarshaling code has not been generated
314f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    yet, issue it before continuing processing.
315f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury
316f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    Args:
317f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury      out_file: The output file.
318f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury      marshalled_types: A set of types for which marshal and unmarshal functions
319f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury          have already been generated.
320f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury      typemap: A dict mapping type names to the corresponding object.
321f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury
322f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    Returns:
323f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury      A string, the name of the type to use for marshaling/unmarshaling.
324f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury
325f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    '''
326f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    if self._base_type:
327f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury      base_type = self._base_type
328f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    else:
329f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury      base_type = self.old_type
330f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    if base_type not in marshalled_types:
331f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury      typemap[base_type].OutputMarshalImpl(
332f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury        out_file, marshalled_types, typemap)
333f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    return base_type
334f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury
3359edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def HasConditional(self):
3369edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Returns true if TPMType has a conditional value."""
3379edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return False
3389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
339595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  def OutputMarshalCall(self, out_file, field):
3409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Write a call to Marshal function for TPMType to |out_file|.
3419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
3429edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       Accumulates a variable 'total_size' with the result of marshaling
3439edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       field |field_name| in structure 'source'.
3449edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
3459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
3469edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
347595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field: A Field object describing this type.
3489edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
349595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    out_file.write(self._MARSHAL_CALL % {'type': field.field_type,
350595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                                         'name': field.field_name})
3519edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
352595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  def OutputUnmarshalCall(self, out_file, field):
3539edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Write a call to Unmarshal function for TPMType to |out_file|.
3549edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
3559edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       Assigns result of unmarshaling field |field_name| in structure 'source'
3569edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       to variable 'result'. Returns if the unmarshalling was unsuccessful.
3579edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
3589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
3599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
360595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field: A Field object describing this type.
3619edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
362907fc8fb669416cb96d603d9d81dacc9ea537170Vadim Bendebury    obj_type = field.field_type
363907fc8fb669416cb96d603d9d81dacc9ea537170Vadim Bendebury    if obj_type == 'TPM_CC':
364907fc8fb669416cb96d603d9d81dacc9ea537170Vadim Bendebury      obj_type = 'UINT32'
365907fc8fb669416cb96d603d9d81dacc9ea537170Vadim Bendebury    out_file.write(self._UNMARSHAL_CALL % {'type': obj_type,
366595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                                           'name': field.field_name})
3679edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
3689edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def _OutputTypedefMarshalDecl(self, out_file, declared_types, typemap):
3699edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Write marshal declarations for TPM typedefs to |out_file|.
3709edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
3719edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       Can only be called on Typedef, ConstantType, AttributeStruct, and
3729edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       Interface objects.
3739edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
3749edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
3759edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
3769edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      declared_types: A set of types for which marshal and unmarshal function
3779edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          declarations have already been generated.
3789edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
3799edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
3809edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.new_type in declared_types:
3819edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return
382595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    if self.old_type not in declared_types and self.old_type in typemap:
3839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap[self.old_type].OutputMarshalDecl(
3849edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          out_file, declared_types, typemap)
3859edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._MARSHAL_DECLARATION % {'type': self.new_type})
3869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    declared_types.add(self.new_type)
3879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
388b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury  def _OutputStructOrUnionMarshalDecl(self, out_file, declared_types):
3899edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Write marshal declarations for a TPM Structure or Union.
3909edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
3919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       Can only be called on Structure and Union objects.
3929edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
3939edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
3949edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
3959edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      declared_types: A set of types for which marshal and unmarshal function
3969edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        declarations have already been generated.
3979edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
3989edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    # TPMU_NAME and TPMU_ENCRYPTED_SECRET type are never used across the
3999edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    # interface.
4009edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if (self.name in declared_types or
4019edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        self.name == 'TPMU_NAME' or
4029edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        self.name == 'TPMU_ENCRYPTED_SECRET'):
4039edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return
4049edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._MARSHAL_DECLARATION % {'type': self.name})
4059edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    declared_types.add(self.name)
4069edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
407595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
4089edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developerclass Typedef(TPMType):
4099edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """Represents a TPM typedef.
4109edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
4119edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  Attributes:
4129edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    old_type: The existing type in a typedef statement.
4139edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    new_type: The new type in a typedef statement.
4149edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """
4159edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # A function to unmarshal a TPM typedef with no extra validation.
4169edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _TYPEDEF_UNMARSHAL_FUNCTION = """
4179edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperTPM_RC %(new_type)s_Unmarshal(
4189edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(new_type)s *target,
4199edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
4209edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size) {
4219edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  return %(old_type)s_Unmarshal(target, buffer, size);
4229edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer}
4239edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
424595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
4259edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def __init__(self, old_type, new_type):
4269edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Initializes a Typedef instance.
4279edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
4289edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
4299edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      old_type: The base type of the attribute structure.
4309edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      new_type: The name of the type.
4319edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
432f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    super(Typedef, self).__init__()
4339edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.old_type = old_type
4349edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.new_type = new_type
4359edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
4369edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
4379edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal implementations for Typedef to |out_file|.
4389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
4399edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
4409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
4419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      marshalled_types: A set of types for which marshal and unmarshal functions
4429edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          have already been generated.
4439edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
4449edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
4459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.new_type in marshalled_types:
4469edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return
447f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    base_type = self._GetBaseType(out_file, marshalled_types, typemap)
448f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    out_file.write(self._TYPEDEF_MARSHAL_FUNCTION % {'old_type': base_type,
4499edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer                                                     'new_type': self.new_type})
4509edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(
451f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury        self._TYPEDEF_UNMARSHAL_FUNCTION % {'old_type': base_type,
4529edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer                                            'new_type': self.new_type})
4539edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    marshalled_types.add(self.new_type)
4549edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
4559edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def OutputMarshalDecl(self, out_file, declared_types, typemap):
4569edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal declarations for Typedef to |out_file|.
4579edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
4589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
4599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
4609edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      declared_types: A set of types for which marshal and unmarshal function
4619edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          declarations have already been generated.
4629edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
4639edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
4649edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self._OutputTypedefMarshalDecl(out_file, declared_types, typemap)
4659edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
466595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
4679edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developerclass ConstantType(TPMType):
4689edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """Represents a TPM Constant type definition.
4699edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
4709edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  Attributes:
4719edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     old_type: The base type of the constant (e.g. 'int').
4729edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     new_type: The name of the type (e.g. 'TPM_RC').
4739edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     valid_values: The list of valid values this type can take (e.g.
4749edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer         'TPM_RC_SUCCESS').
4759edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     error_code: Error to be returned when unmarshalling is unsuccessful.
4769edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """
4779edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _CHECK_VALUE = """
4789edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (*target == %(value)s) {
4799edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return TPM_RC_SUCCESS;
4809edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
4819edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _CHECK_VALUE_IFDEF = """
4829edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer#ifdef %(value)s
4839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (*target == %(value)s) {
4849edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return TPM_RC_SUCCESS;
4859edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }
4869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer#endif"""
4879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _UNMARSHAL_END = """
4889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  return %(error_code)s;
4899edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer}
4909edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
4919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _IFDEF_TYPE_RE = re.compile(r'^TPM_(ALG|CC).*')
4929edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
4939edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def __init__(self, old_type, new_type):
4949edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Initializes a ConstantType instance.
4959edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
4969edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Values are added to valid_values attribute during parsing.
4979edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
4989edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
4999edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      old_type: The base type of the constant type.
5009edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      new_type: The name of the type.
5019edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
502f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    super(ConstantType, self).__init__()
5039edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.old_type = old_type
5049edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.new_type = new_type
5059edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.valid_values = []
5069edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.error_code = 'TPM_RC_VALUE'
5079edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
5089edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def _NeedsIfdef(self):
5099edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Returns True if new_type is a type which needs ifdef enclosing."""
5109edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return self._IFDEF_TYPE_RE.search(self.new_type)
5119edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
5129edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
5139edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal implementations for ConstantType to |out_file|.
5149edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
5159edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
5169edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
5179edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      marshalled_types: A set of types for which marshal and unmarshal functions
5189edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          have already been generated.
5199edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
5209edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
5219edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.new_type in marshalled_types:
5229edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return
523f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    base_type = self._GetBaseType(out_file, marshalled_types, typemap)
524f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    out_file.write(self._TYPEDEF_MARSHAL_FUNCTION % {'old_type': base_type,
5259edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer                                                     'new_type': self.new_type})
526f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    out_file.write(self._TYPEDEF_UNMARSHAL_START % {'old_type': base_type,
5279edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer                                                    'new_type': self.new_type})
5289edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    for value in self.valid_values:
5299edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if self._NeedsIfdef():
5309edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(self._CHECK_VALUE_IFDEF % {'value': value})
5319edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      else:
5329edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(self._CHECK_VALUE % {'value': value})
5339edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._UNMARSHAL_END % {'error_code': self.error_code})
5349edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    marshalled_types.add(self.new_type)
5359edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
5369edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def OutputMarshalDecl(self, out_file, declared_types, typemap):
5379edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal declarations for ConstantType to |out_file|.
5389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
5399edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
5409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
5419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      declared_types: A set of types for which marshal and unmarshal function
5429edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          declarations have already been generated.
5439edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
5449edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
5459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self._OutputTypedefMarshalDecl(out_file, declared_types, typemap)
5469edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
547595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
5489edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developerclass AttributeStructure(TPMType):
5499edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """Represents a TPM attribute structure type definition.
5509edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
5519edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  Attributes:
5529edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     old_type: The base type of the constant (e.g. 'int').
5539edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     new_type: The name of the type (e.g. 'TPMA_OBJECT').
5549edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     reserved: The list of bit bounds where bits must be 0 (e.g. ['10_2','3']).
5559edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """
5569edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # Attribute structures need an explicit cast to the base type.
5579edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _ATTRIBUTE_MARSHAL_FUNCTION = """
5589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperUINT16 %(new_type)s_Marshal(
5599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(new_type)s *source,
5609edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
5619edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size) {
5629edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  return %(old_type)s_Marshal((%(old_type)s*)source, buffer, size);
5639edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer}
5649edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
5659edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _ATTRIBUTE_UNMARSHAL_START = """
5669edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperTPM_RC %(new_type)s_Unmarshal(
5679edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(new_type)s *target,
5689edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
5699edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size) {
5709edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  TPM_RC result;
5719edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  result = %(old_type)s_Unmarshal((%(old_type)s*)target, buffer, size);
5729edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (result != TPM_RC_SUCCESS) {
5739edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return result;
5749edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
5759edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _CHECK_RESERVED = """
5769edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (target->reserved%(bits)s != 0) {
5779edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return TPM_RC_RESERVED_BITS;
5789edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
5799edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
5809edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def __init__(self, old_type, new_type):
5819edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Initializes an AttributeStructure instance.
5829edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
5839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Values may be added to reserved attribute during parsing.
5849edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
5859edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
5869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      old_type: The base type of the attribute structure.
5879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      new_type: The name of the type.
5889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
589f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    super(AttributeStructure, self).__init__()
5909edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.old_type = old_type
5919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.new_type = new_type
5929edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.reserved = []
5939edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
5949edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
5959edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal implementations for AttributStructure to |out_file|.
5969edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
5979edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
5989edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
5999edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      marshalled_types: A set of types for which marshal and unmarshal functions
6009edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          have already been generated.
6019edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
6029edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
6039edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.new_type in marshalled_types:
6049edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return
605f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    base_type = self._GetBaseType(out_file, marshalled_types, typemap)
6069edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._ATTRIBUTE_MARSHAL_FUNCTION %
607f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury                   {'old_type': base_type,
608b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                    'new_type': self.new_type})
6099edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._ATTRIBUTE_UNMARSHAL_START %
610f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury                   {'old_type': base_type,
611b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                    'new_type': self.new_type})
6129edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    for bits in self.reserved:
6139edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(self._CHECK_RESERVED % {'bits': bits})
6149edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._UNMARSHAL_END)
6159edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    marshalled_types.add(self.new_type)
6169edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
6179edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def OutputMarshalDecl(self, out_file, declared_types, typemap):
6189edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal declarations for AttributeStructure to |out_file|.
6199edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
6209edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
6219edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
6229edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      declared_types: A set of types for which marshal and unmarshal function
6239edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          declarations have already been generated.
6249edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
6259edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
6269edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self._OutputTypedefMarshalDecl(out_file, declared_types, typemap)
6279edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
628595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
6299edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developerclass Interface(TPMType):
6309edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """Represents a TPM interface type definition.
6319edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
6329edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  Attributes:
6339edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     old_type: The base type of the interface (e.g. 'TPM_HANDLE').
6349edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     new_type: The name of the type (e.g. 'TPMI_DH_OBJECT').
6359edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     valid_values: List of valid values for new_type. If this is not empty,
6369edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer         valid values for new_type is explicitly defined in the spec.
6379edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     bounds: List of pairs representing bounds. If nonempty, target must fall
6389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer         between one of these bounds.
6399edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     conditional_value: Name of conditionally allowed value. If there is no
6409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer         such value, this variable will be None.
6419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     supported_values: String literal indicating the name of a list of supported
6429edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer         values to be substituted at compile time (e.g. 'AES_KEY_SIZES_BITS').
6439edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer         If this is not None, valid values for new_type depends on the
6449edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer         implementation.
6459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer     error_code: Return code when an unmarshalling error occurs.
6469edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """
647fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  _INTERFACE_CONDITIONAL_UNMARSHAL_START = """
6489edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperTPM_RC %(new_type)s_Unmarshal(
6499edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(new_type)s *target,
6509edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
6519edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size,
6529edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BOOL allow_conditional_value) {
653fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  TPM_RC result;"""
654fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  _INTERFACE_UNMARSHAL_START = """
655fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn BohrTPM_RC %(new_type)s_Unmarshal(
656fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr    %(new_type)s *target,
657fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr    BYTE **buffer,
658fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr    INT32 *size) {
659fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  TPM_RC result;"""
660fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  _UNMARSHAL_VALUE = """
6619edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  result = %(old_type)s_Unmarshal(target, buffer, size);
6629edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (result != TPM_RC_SUCCESS) {
6639edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return result;
6649edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
665907fc8fb669416cb96d603d9d81dacc9ea537170Vadim Bendebury  _UNMARSHAL_VALUE_ALLOW_RC_VALUE = """
666907fc8fb669416cb96d603d9d81dacc9ea537170Vadim Bendebury  result = %(old_type)s_Unmarshal(target, buffer, size);
667907fc8fb669416cb96d603d9d81dacc9ea537170Vadim Bendebury  if ((result != TPM_RC_VALUE) && (result != TPM_RC_SUCCESS)) {
668907fc8fb669416cb96d603d9d81dacc9ea537170Vadim Bendebury    return result;
669907fc8fb669416cb96d603d9d81dacc9ea537170Vadim Bendebury  }"""
670fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  _SETUP_CHECK_SUPPORTED_VALUES = """
6719edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  uint16_t supported_values[] = %(supported_values)s;
6729edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  size_t length = sizeof(supported_values)/sizeof(supported_values[0]);
6739edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  size_t i;
674fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  BOOL is_supported_value = FALSE;"""
675fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  _CHECK_SUPPORTED_VALUES = """
6769edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  for (i = 0; i < length; ++i) {
6779edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if (*target == supported_values[i]) {
6789edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      is_supported_value = TRUE;
6799edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      break;
6809edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    }
6819edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }
6829edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (!is_supported_value) {
6839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return %(error_code)s;
6849edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
6859edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _CHECK_CONDITIONAL = """
6869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (*target == %(name)s) {
6879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return allow_conditional_value ? TPM_RC_SUCCESS : %(error_code)s;
6889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
689fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  _SETUP_CHECK_VALUES = '\n  BOOL has_valid_value = FALSE;'
6909edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _VALUE_END_SWITCH = """
6919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      has_valid_value = TRUE;
6929edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      break;
6939edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
6949edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _CHECK_BOUND = """
6959edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if((*target >= %(lower)s) && (*target <= %(upper)s)) {
6969edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    has_valid_value = TRUE;
6979edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
6989edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _CHECK_VALUES_END = """
6999edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (!has_valid_value) {
7009edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return %(error_code)s;
7019edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
7029edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _CONDITIONAL_MARSHAL_DECLARATION = """
7039edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperUINT16 %(type)s_Marshal(
7049edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(type)s *source,
7059edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
7069edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size);
7079edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
7089edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperTPM_RC %(type)s_Unmarshal(
7099edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(type)s *target,
7109edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
7119edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size,
7129edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BOOL allow_conditioanl_value);
7139edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
7149edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _CONDITIONAL_UNMARSHAL_CALL = """
7159edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  result = %(type)s_Unmarshal(
7169edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      &target->%(name)s, buffer, size, %(flag)s);
7179edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (result != TPM_RC_SUCCESS) {
7189edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return result;
7199edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
7209edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _IFDEF_TYPE_RE = re.compile(r'^TPMI_(ALG|ECC)_.*')
7219edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
7229edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def __init__(self, old_type, new_type):
7239edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Initializes an Interface instance.
7249edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
7259edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Values may be added/assigned to valid_values, bounds, conditional_value,
7269edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    supported_values, and error_code attributes new values during parsing.
7279edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
7289edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
7299edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      old_type: The base type of the interface.
7309edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      new_type: The name of the type.
7319edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
732f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    super(Interface, self).__init__()
7339edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.old_type = old_type
7349edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.new_type = new_type
7359edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.valid_values = []
7369edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.bounds = []
7379edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.conditional_value = None
7389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.supported_values = None
7399edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.error_code = 'TPM_RC_VALUE'
7409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
7419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def HasConditional(self):
7429edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Returns true if Interface has a valid conditional_value."""
743595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    return self.conditional_value is not None
7449edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
7459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def _NeedsIfdef(self):
7469edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Returns True if new_type is a type which needs ifdef enclosing."""
7479edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return self._IFDEF_TYPE_RE.search(self.new_type)
7489edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
7499edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
7509edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal implementation for Interface to |out_file|.
7519edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
7529edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
7539edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
7549edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      marshalled_types: A set of types for which marshal and unmarshal functions
7559edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          have already been generated.
7569edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
7579edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
7589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.new_type in marshalled_types:
7599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return
760f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    base_type = self._GetBaseType(out_file, marshalled_types, typemap)
761f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    out_file.write(self._TYPEDEF_MARSHAL_FUNCTION % {'old_type': base_type,
7629edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer                                                     'new_type': self.new_type})
7639edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.conditional_value:
764fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr      out_file.write(self._INTERFACE_CONDITIONAL_UNMARSHAL_START %
765f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury                     {'old_type': base_type,
766b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                      'new_type': self.new_type})
7679edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    else:
7689edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(
769f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury          self._INTERFACE_UNMARSHAL_START % {'old_type': base_type,
770fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr                                             'new_type': self.new_type})
771fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr    # Creating necessary local variables.
772fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr    if self.supported_values:
773fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr      out_file.write(self._SETUP_CHECK_SUPPORTED_VALUES %
774b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                     {'supported_values': self.supported_values})
775fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr    if len(self.valid_values)+len(self.bounds) > 0:
776fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr      out_file.write(self._SETUP_CHECK_VALUES)
777907fc8fb669416cb96d603d9d81dacc9ea537170Vadim Bendebury      out_file.write(self._UNMARSHAL_VALUE_ALLOW_RC_VALUE %
778f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury                     {'old_type': base_type})
779907fc8fb669416cb96d603d9d81dacc9ea537170Vadim Bendebury    else:
780f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury      out_file.write(self._UNMARSHAL_VALUE % {'old_type': base_type})
781fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr
7829edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.supported_values:
7839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(self._CHECK_SUPPORTED_VALUES %
784b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                     {'supported_values': self.supported_values,
785b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                      'error_code': self.error_code})
7869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.conditional_value:
7879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(
7889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          self._CHECK_CONDITIONAL % {'name': self.conditional_value,
7899edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer                                     'error_code': self.error_code})
7909edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    # Checking for valid values.
7919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if len(self.valid_values)+len(self.bounds) > 0:
792595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      if self.valid_values:
7939edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(self._VALUE_START_SWITCH % {'name': '*target'})
7949edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        for value in self.valid_values:
7959edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          if self._NeedsIfdef():
7969edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer            out_file.write(self._VALUE_CASE_IFDEF % {'value': value})
7979edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          else:
7989edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer            out_file.write(self._VALUE_CASE % {'value': value})
7999edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(self._VALUE_END_SWITCH)
8009edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      for (lower, upper) in self.bounds:
8019edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(
8029edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer            self._CHECK_BOUND % {'lower': lower, 'upper': upper})
8039edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(self._CHECK_VALUES_END % {'error_code': self.error_code})
8049edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
8059edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._UNMARSHAL_END)
8069edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    marshalled_types.add(self.new_type)
8079edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
8089edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def OutputMarshalDecl(self, out_file, declared_types, typemap):
8099edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal declarations for Interface to |out_file|.
8109edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
8119edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       Outputted declaration depends on whether Interface type has a
8129edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       conditionally valid value.
8139edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
8149edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
8159edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
8169edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      declared_types: A set of types for which marshal and unmarshal function
8179edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          declarations have already been generated.
8189edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
8199edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
8209edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.new_type in declared_types:
8219edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return
8229edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.old_type not in declared_types:
8239edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap[self.old_type].OutputMarshalDecl(
8249edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          out_file, declared_types, typemap)
8259edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.HasConditional():
8269edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(
8279edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          self._CONDITIONAL_MARSHAL_DECLARATION % {'type': self.new_type})
8289edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    else:
8299edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(self._MARSHAL_DECLARATION % {'type': self.new_type})
8309edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    declared_types.add(self.new_type)
8319edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
8329edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def OutputUnmarshalCall(
833595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      self, out_file, field):
8349edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Write a call to Unmarshal function for Interface type to |out_file|.
8359edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
8369edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       Override TPMType OutputUnmarshalCall because when an Interface type has
8379edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       a conditionally valid value, a BOOL value (|conditional_valid|) is passed
8389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       as a parameter.
8399edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
8409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
8419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
842595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field: A Field object representing an element of this interface.
8439edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
8449edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.conditional_value:
8459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(
846595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury          self._CONDITIONAL_UNMARSHAL_CALL % {'type': field.field_type,
847595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                                              'name': field.field_name,
848595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                                              'flag': field.conditional_value})
8499edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    else:
850595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      out_file.write(self._UNMARSHAL_CALL % {'type': field.field_type,
851595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                                             'name': field.field_name})
852595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
8539edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
8549edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developerclass Structure(TPMType):
8559edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """Represents a TPM structure.
8569edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
8579edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  Attributes:
8589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    name: The name of the structure.
8599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    fields: A list of Field objects representing struct fields.
8609edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    upper_bounds: A dictionary of (name, val) tuples mapping name to max val.
8619edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    lower_bounds: A dictionary of (name, val) tuples mapping name to min val.
8629edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    size_check: Set if TPM2B structure must be size checked (triggered by size=)
8639edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    valid_tag_values: A list of values field tag is allowed to take.
8649edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    error_code: The return code to be returned if an error occurs
8659edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """
8669edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _STRUCTURE_MARSHAL_START = """
8679edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperUINT16 %(name)s_Marshal(
8689edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(name)s *source,
8699edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
8709edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size) {
8719edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  UINT16 total_size = 0;"""
8729edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _STRUCTURE_UNMARSHAL_START = """
8739edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperTPM_RC %(name)s_Unmarshal(
8749edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(name)s *target,
8759edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
8769edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size) {
8779edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  TPM_RC result;"""
8789edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _MARSHAL_END = '\n  return total_size;\n}\n'
879fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  _SETUP_ARRAY_FIELD = '\n  INT32 i;'
880fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  _CHECK_SIZE_START = """
881fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  UINT32 start_size = *size;
882fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  UINT32 struct_size;"""
8839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _CHECK_SIZE_END = """
884fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr  struct_size = start_size - *size - sizeof(target->t.size);
8859edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (struct_size != target->t.size) {
8869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return TPM_RC_SIZE;
8879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
8889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _TPM2B_ZERO_SIZE = """
8899edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (target->t.size == 0) {
8909edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return %(return_value)s;
8919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
8929edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _CHECK_BOUND = """
8939edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (target->%(name)s %(operator)s %(bound_value)s) {
8949edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return %(error_code)s;
8959edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
896b8c5ecc6967ef4f63f4fca949db819be74dc2b4bVadim Bendebury  _FIX_SIZE_FIELD = """
897b8c5ecc6967ef4f63f4fca949db819be74dc2b4bVadim Bendebury  {
898b8c5ecc6967ef4f63f4fca949db819be74dc2b4bVadim Bendebury    BYTE *size_location = *buffer - total_size;
899b8c5ecc6967ef4f63f4fca949db819be74dc2b4bVadim Bendebury    INT32 size_field_size = sizeof(%(size_field_type)s);
900b8c5ecc6967ef4f63f4fca949db819be74dc2b4bVadim Bendebury    UINT16 payload_size = total_size - (UINT16)size_field_size;
901b8c5ecc6967ef4f63f4fca949db819be74dc2b4bVadim Bendebury    %(size_field_type)s_Marshal(&payload_size,
902b8c5ecc6967ef4f63f4fca949db819be74dc2b4bVadim Bendebury      &size_location, &size_field_size);
903b8c5ecc6967ef4f63f4fca949db819be74dc2b4bVadim Bendebury  }"""
9049edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9059edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def __init__(self, name):
9069edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Initializes a Structure instance.
9079edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9089edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Initially the instance will have no fields, upper_bounds, lower_bounds, or
9099edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    valid_tag_values. Those can be added with AddField(), AddUpperBound(),
9109edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    AddLowerBound(), and AddTagVal() methods.
9119edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9129edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
9139edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      name: The name of the structure.
9149edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
915f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    super(Structure, self).__init__()
9169edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.name = name
9179edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.fields = []
9189edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.upper_bounds = {}
9199edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.lower_bounds = {}
9209edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.size_check = False
9219edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.valid_tag_values = []
9229edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.error_code = 'TPM_RC_VALUE'
9239edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
924595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  def AddField(self, field):
9259edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Adds a field to fields attribute in Structure.
9269edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9279edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
928595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field: Instance of Field
9299edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
930595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    self.fields.append(field)
9319edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9329edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def AddUpperBound(self, field_name, value):
9339edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Adds an upper bound for a field.
9349edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9359edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
9369edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       field_name: Name of field with bound.
9379edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       value: Value of upper bound.
9389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
939595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    if _IsTPM2B(self.name):
9409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      field_name = 't.' + field_name
9419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.upper_bounds[field_name] = value
9429edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9439edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def AddLowerBound(self, field_name, value):
9449edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Adds a lower bound for a field.
9459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9469edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
9479edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       field_name: Name of field with bound.
9489edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       value: Value of lower bound.
9499edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
950595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    if _IsTPM2B(self.name):
9519edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      field_name = 't.' + field_name
9529edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.lower_bounds[field_name] = value
9539edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
954595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  def _AddTagValue(self, value):
9559edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Adds a valid value for tag field.
9569edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9579edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
9589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       value: Valid value for tag field.
9599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
9609edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.valid_tag_values.append(value)
9619edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9629edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def _GetFieldTypes(self):
9639edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Creates a set which holds all current field types.
9649edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9659edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Returns:
9669edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      A set of field types.
9679edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
9689edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return set([field.field_type for field in self.fields])
9699edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9709edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
9719edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal implementations for Structure to |out_file|.
9729edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9739edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
9749edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
9759edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      marshalled_types: A set of types for which marshal and unmarshal functions
9769edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          have already been generated.
9779edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
9789edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
9799edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.name in marshalled_types:
9809edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return
981595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
9829edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    # Make sure any dependencies already have marshal functions defined.
9839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    for field_type in self._GetFieldTypes():
9849edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if field_type not in marshalled_types:
9859edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        typemap[field_type].OutputMarshalImpl(
9869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer            out_file, marshalled_types, typemap)
9879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        marshalled_types.add(field_type)
9889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
9899edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._STRUCTURE_MARSHAL_START % {'name': self.name})
990fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr    # If any field is an array, create local variable INT32 i.
991fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr    for field in self.fields:
992595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      if field.array_size:
993fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr        out_file.write(self._SETUP_ARRAY_FIELD)
994fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr        break
9959edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    for field in self.fields:
996595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # Each TPM2B is a union of two sized buffers, one which is type specific
997595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # (the 't' element) and the other is a generic value (the 'b' element).
998595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # For this reason a 't.' is prepended for fields in a TPM2B type. See
999595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # section 9.11.6 in TCG TPM2.0 Library Specification, Part 2: Structures
1000595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # for more details.
1001595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      if _IsTPM2B(self.name):
1002595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        field.field_name = 't.' + field.field_name
1003595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        if field.run_time_size:
1004595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury          field.run_time_size = 't.' + field.run_time_size
10059edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      field.OutputMarshal(out_file, typemap)
1006b8c5ecc6967ef4f63f4fca949db819be74dc2b4bVadim Bendebury    if self.size_check:
1007b8c5ecc6967ef4f63f4fca949db819be74dc2b4bVadim Bendebury      out_file.write(self._FIX_SIZE_FIELD % {'size_field_type': self.fields[0].field_type})
10089edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._MARSHAL_END)
10099edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
10109edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._STRUCTURE_UNMARSHAL_START % {'name': self.name})
10119edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.size_check:
10129edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(self._CHECK_SIZE_START)
1013fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr    # If any field is an array, create local variable INT32 i.
1014fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr    for field in self.fields:
1015595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      if field.array_size:
1016fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr        out_file.write(self._SETUP_ARRAY_FIELD)
1017fb668129d13e02e4f9feec53d519df84d96bb5fdJocelyn Bohr        break
10189edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    for field in self.fields:
10199edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      field.OutputUnmarshal(out_file, typemap)
10209edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return_value = self.error_code
10219edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if field.field_name == 't.size' and self.size_check:
10229edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(self._TPM2B_ZERO_SIZE % {'return_value': 'TPM_RC_SIZE'})
10239edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if field.field_name == 't.size' and not self.size_check:
10249edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(
10259edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer            self._TPM2B_ZERO_SIZE % {'return_value': 'TPM_RC_SUCCESS'})
10269edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if field.field_name in self.upper_bounds:
10279edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        if (field.field_name == 'count' or
10289edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer            field.field_name == 't.size' or
10299edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer            field.field_name == 'size'):
10309edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          return_value = 'TPM_RC_SIZE'
10319edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(self._CHECK_BOUND %
1032b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                       {'name': field.field_name,
1033b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                        'operator': '>',
1034b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                        'bound_value': self.upper_bounds[field.field_name],
1035b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                        'error_code': return_value})
10369edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if field.field_name in self.lower_bounds:
10379edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        if (field.field_name == 'count' or
10389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer            field.field_name == 't.size' or
10399edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer            field.field_name == 'size'):
10409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          return_value = 'TPM_RC_SIZE'
10419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(self._CHECK_BOUND %
1042b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                       {'name': field.field_name,
1043b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                        'operator': '<',
1044b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                        'bound_value': self.lower_bounds[field.field_name],
1045b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury                        'error_code': return_value})
1046595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      if field.field_name == 'tag' and self.valid_tag_values:
10479edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(self._VALUE_START_SWITCH % {'name': 'target->tag'})
10489edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        for value in self.valid_tag_values:
10499edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          out_file.write(self._VALUE_CASE % {'value': value})
10509edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(self._VALUE_END_SWITCH % {'error_code': 'TPM_RC_TAG'})
10519edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if self.size_check:
10529edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(self._CHECK_SIZE_END)
1053595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    if not self.fields:
1054595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # The spec includes a definition of an empty structure, as a side effect
1055595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # the marshaling/unmarshaling functions become empty, the compiler
1056595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      # warning is suppressed by the below statement.
1057595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      out_file.write('  (void)result;\n')
10589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._UNMARSHAL_END)
10599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
10609edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    marshalled_types.add(self.name)
10619edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
1062b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury  def OutputMarshalDecl(self, out_file, declared_types, _):
10639edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal declarations for Structure to |out_file|.
10649edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
10659edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
10669edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
10679edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      declared_types: A set of types for which marshal and unmarshal function
10689edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          declarations have already been generated.
10699edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
1070b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury    self._OutputStructOrUnionMarshalDecl(out_file, declared_types)
10719edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
1072595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
10739edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developerclass Union(TPMType):
10749edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """Represents a TPM union.
10759edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
10769edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  Attributes:
10779edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    name: The name of the union.
10789edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    fields: A list of Field objects representing union fields.
10799edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """
10809edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
10819edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _UNION_MARSHAL_START = """
10829edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperUINT16 %(name)s_Marshal(
10839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(name)s *source,
10849edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
10859edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size,
10869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    UINT32 selector) {
10871f2ef97bdde4318c3cc254bbafdab65bfc729911Vadim Bendebury  %(array_extras)s
10889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  switch(selector) {"""
10899edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _UNION_UNMARSHAL_START = """
10909edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperTPM_RC %(name)s_Unmarshal(
10919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(name)s *target,
10929edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
10939edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size,
10949edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    UINT32 selector) {
10959edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  switch(selector) {"""
10969edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _MARSHAL_END = '\n  }\n  return 0;\n}\n'
10979edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _UNMARSHAL_END = '\n  }\n  return TPM_RC_SELECTOR;\n}\n'
10989edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _MARSHAL_DECLARATION = """
10999edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperUINT16 %(type)s_Marshal(
11009edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(type)s *source,
11019edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
11029edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size,
11039edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    UINT32 selector);
11049edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
11059edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS DeveloperTPM_RC %(type)s_Unmarshal(
11069edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    %(type)s *target,
11079edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    BYTE **buffer,
11089edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 *size,
11099edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    UINT32 selector);
11109edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer"""
11115aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr  _CASE_SELECTOR = """
11125aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr    case %(selector)s:"""
11135aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr  _MARSHAL_EMPTY = """
11145aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr      return 0;"""
11155aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr  _UNMARSHAL_EMPTY = """
11165aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr      return TPM_RC_SUCCESS;"""
11179edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _MARSHAL_FIELD = """
11189edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return %(type)s_Marshal(
11199edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          (%(type)s*)&source->%(name)s, buffer, size);"""
11209edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _UNMARSHAL_FIELD = """
11219edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return %(type)s_Unmarshal(
11229edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          (%(type)s*)&target->%(name)s, buffer, size);"""
11239edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _SETUP_MARSHAL_FIELD_ARRAY = """
11249edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 i;
11259edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    UINT16 total_size = 0;"""
11269edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _SETUP_UNMARSHAL_FIELD_ARRAY = """
11279edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    INT32 i;
11289edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    TPM_RC result = TPM_RC_SUCCESS;"""
11299edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _MARSHAL_FIELD_ARRAY = """
11309edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    for (i = 0; i < %(array_length)s; ++i) {
11319edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      total_size += %(type)s_Marshal(
11329edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          &source->%(name)s[i], buffer, size);
11339edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    }
11349edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return total_size;"""
11359edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _UNMARSHAL_FIELD_ARRAY = """
11369edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    for (i = 0; i < %(array_length)s; ++i) {
11379edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      result = %(type)s_Unmarshal(
11389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          &target->%(name)s[i], buffer, size);
11399edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if (result != TPM_RC_SUCCESS) {
11409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        return result;
11419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      }
11429edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    }
11439edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return TPM_RC_SUCCESS;"""
11449edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _UNMARSHAL_FIELD_CONDITIONAL = """
11459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return %(type)s_Unmarshal(
11469edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        &target->%(name)s, buffer, size, FALSE);"""
11479edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _UNION_MARSHAL_CALL = """
11489edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  total_size += %(type)s_Marshal(
11499edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      &source->%(name)s, buffer, size, source->%(selector)s);"""
11509edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _UNION_UNMARSHAL_CALL = """
11519edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  result = %(type)s_Unmarshal(
11529edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      &target->%(name)s, buffer, size, target->%(selector)s);
11539edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  if (result != TPM_RC_SUCCESS) {
11549edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return result;
11559edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  }"""
11569edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _IFDEF = '\n#ifdef %(type)s'
11579edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _ENDIF = '\n#endif'
11589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  _IFDEF_TYPE_RE = re.compile(r'^TPM_(ALG|CC).*')
11599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
11609edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def __init__(self, name):
11619edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Initializes a Union instance.
11629edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
11639edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Initially the instance will have no fields. Fields are added with the
11649edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    AddField() method.
11659edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
11669edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
11679edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      name: The name of the structure.
11689edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
1169f5af8595c277e36541c688f7803e106cebb65fd2Vadim Bendebury    super(Union, self).__init__()
11709edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.name = name
11719edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    self.fields = []
11729edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
11739edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def _NeedsIfdef(self, selector):
11749edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Returns True if selector is a type which needs ifdef enclosing."""
11759edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    return self._IFDEF_TYPE_RE.search(selector)
11769edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
1177595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  def AddField(self, field):
11789edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Adds a field to fields attribute in Union.
11799edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
11809edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
1181595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field: instance of Field
11829edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
11837cba233744eb02495f33aab5e5f28efbff87075dJocelyn Bohr    # xor is a C++ keyword and must be fixed.
1184595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    if field.field_name == 'xor':
1185595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field.field_name = 'xor_'
1186595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    self.fields.append(field)
11879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
11889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def _OutputMarshalField(
1189b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury      self, out_file, field_type, field_name, array_length):
11909edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Write a call to marshal a field in this union.
11919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
11929edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
11939edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
11949edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      field_type: The type of field.
1195595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field_name: The name of the field.
11969edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      array_length: Variable indicating length of array, None if field is not
11979edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          an array.
11989edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
11999edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if array_length:
12009edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(self._MARSHAL_FIELD_ARRAY % {'type': field_type,
12019edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer                                                  'name': field_name,
12025aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr                                                  'array_length': array_length})
12039edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    else:
12049edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(self._MARSHAL_FIELD % {'type': field_type,
12055aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr                                            'name': field_name})
12069edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
12079edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def _OutputUnmarshalField(
1208b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury      self, out_file, field_type, field_name, array_length, typemap):
12099edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Write a call to unmarshal a field in this union.
12109edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
12119edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
1212595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      out_file: The output file object.
12139edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      field_type: The type of field.
1214595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field_name: The name of the field.
12159edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      array_length: Variable indicating length of array, None if field is not
12169edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          an array.
12179edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
12189edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
12199edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if array_length:
12209edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(
12219edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          self._UNMARSHAL_FIELD_ARRAY % {'type': field_type,
12229edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer                                         'name': field_name,
12235aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr                                         'array_length': array_length})
12249edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    elif typemap[field_type].HasConditional():
12259edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(
12269edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          self._UNMARSHAL_FIELD_CONDITIONAL % {'type': field_type,
12275aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr                                               'name': field_name})
12289edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    else:
12299edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(self._UNMARSHAL_FIELD % {'type': field_type,
12305aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr                                              'name': field_name})
12319edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
12329edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  def OutputMarshalImpl(self, out_file, marshalled_types, typemap):
12339edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal implementations for Union to |out_file|.
12349edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
12359edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
12369edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
12379edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      marshalled_types: A set of types for which marshal and unmarshal functions
12389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          have already been generated.
12399edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      typemap: A dict mapping type names to the corresponding object.
12409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
12419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    if (self.name in marshalled_types or
12429edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        self.name == 'TPMU_NAME' or
1243595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        self.name == 'TPMU_ENCRYPTED_SECRET' or
1244595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        not self.fields):
12459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      return
1246595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
12479edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    field_types = {f.field_name: f.field_type for f in self.fields}
1248595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    array_lengths = {}
1249595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    for f in self.fields:
1250595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      if f.array_size:
1251595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        array_lengths[f.field_name] = f.array_size
1252595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      else:
1253595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        array_lengths[f.field_name] = None
1254595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury
12559edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    # Make sure any dependencies already have marshal functions defined.
1256595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    for field_type in field_types.itervalues():
12579edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if field_type not in marshalled_types:
12589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        typemap[field_type].OutputMarshalImpl(
12599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer            out_file, marshalled_types, typemap)
12609edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        marshalled_types.add(field_type)
1261595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    if self.fields[0].array_size:
12621f2ef97bdde4318c3cc254bbafdab65bfc729911Vadim Bendebury      array_extras = self._SETUP_MARSHAL_FIELD_ARRAY
12631f2ef97bdde4318c3cc254bbafdab65bfc729911Vadim Bendebury    else:
12641f2ef97bdde4318c3cc254bbafdab65bfc729911Vadim Bendebury      array_extras = ''
12651f2ef97bdde4318c3cc254bbafdab65bfc729911Vadim Bendebury    out_file.write(self._UNION_MARSHAL_START % {'name': self.name,
12661f2ef97bdde4318c3cc254bbafdab65bfc729911Vadim Bendebury                                                'array_extras': array_extras})
12671f2ef97bdde4318c3cc254bbafdab65bfc729911Vadim Bendebury    # Set up variables if Union is an array type.
1268595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    for field in self.fields:
1269595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      selector = field.selector_value
1270595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      if not selector:
1271595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        continue
1272595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field_name = field.field_name
12735aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr      if self._NeedsIfdef(selector):
12745aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr        out_file.write(self._IFDEF % {'type': selector})
1275595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      out_file.write(self._CASE_SELECTOR % {'selector': selector})
12765aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr      # Selector is not associated with a name, so no marshaling occurs.
12779edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if not field_name:
12785aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr        out_file.write(self._MARSHAL_EMPTY)
12795aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr        if self._NeedsIfdef(selector):
12805aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr          out_file.write(self._ENDIF)
12819edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        continue
12829edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      field_type = field_types[field_name]
12839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      array_length = array_lengths[field_name]
1284b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury      self._OutputMarshalField(out_file, field_type, field_name, array_length)
12859edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if self._NeedsIfdef(selector):
12869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(self._ENDIF)
12879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._MARSHAL_END)
12889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._UNION_UNMARSHAL_START % {'name': self.name})
12899edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    # Set up variables if Union is an array type.
1290595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    if self.fields[0].array_size:
12919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file.write(self._SETUP_UNMARSHAL_FIELD_ARRAY)
1292595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    for field in self.fields:
1293595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      selector = field.selector_value
1294595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      if not selector:
1295595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury        continue
1296595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field_name = field.field_name
12975aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr      if self._NeedsIfdef(selector):
12985aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr        out_file.write(self._IFDEF % {'type': selector})
12995aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr      out_file.write(self._CASE_SELECTOR % {'selector': selector})
13005aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr      # Selector is not associated with a name, so no unmarshaling occurs.
13019edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if not field_name:
13025aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr        out_file.write(self._UNMARSHAL_EMPTY)
13035aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr        if self._NeedsIfdef(selector):
13045aef9c6461983184408bb4ca0747c7c124b38903Jocelyn Bohr          out_file.write(self._ENDIF)
13059edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        continue
13069edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      field_type = field_types[field_name]
13079edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      array_length = array_lengths[field_name]
13089edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      self._OutputUnmarshalField(
1309b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury          out_file, field_type, field_name, array_length, typemap)
13109edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      if self._NeedsIfdef(selector):
13119edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer        out_file.write(self._ENDIF)
13129edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(self._UNMARSHAL_END)
13139edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    marshalled_types.add(self.name)
13149edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
1315b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury  def OutputMarshalDecl(self, out_file, declared_types, _):
13169edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Writes marshal declarations for Union to |out_file|.
13179edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
13189edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
13199edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
13209edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      declared_types: A set of types for which marshal and unmarshal function
13219edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer          declarations have already been generated.
13229edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
1323b85286c8c88af688bd3f1f31a269dfae51f57689Vadim Bendebury    self._OutputStructOrUnionMarshalDecl(out_file, declared_types)
13249edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
1325595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  def OutputMarshalCall(self, out_file, field):
13269edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Write a call to marshal function for Union type to |out_file|.
13279edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
13289edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       Override TPMType OutputMarshalCall to pass in selector value.
13299edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
13309edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
13319edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
1332595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field: A Field object representing a member of this union
13339edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
1334595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    out_file.write(self._UNION_MARSHAL_CALL %
1335595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                   {'type': field.field_type,
1336595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                    'name': field.field_name,
1337595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                    'selector': field.selector_value})
13389edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
1339595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  def OutputUnmarshalCall(self, out_file, field):
13409edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """Write a call to unmarshal function for Union type to |out_file|.
13419edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
13429edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer       Override TPMType OutputUnmashalCall to pass in selector value.
13439edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
13449edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    Args:
13459edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer      out_file: The output file.
1346595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury      field: A Field object representing a member of this union
13479edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    """
1348595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    out_file.write(self._UNION_UNMARSHAL_CALL %
1349595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                   {'type': field.field_type,
1350595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                    'name': field.field_name,
1351595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury                    'selector': field.selector_value})
13529edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
13539edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
13543cd8526c535baca0947adccb82f8ef71cb45ba4cVadim Bendeburydef GenerateHeader(typemap):
13559edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """Generates a header file with declarations for all given generator objects.
13569edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
13579edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  Args:
13589edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    typemap: A dict mapping type names to the corresponding object.
13599edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """
13609edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  out_file = open(_OUTPUT_FILE_H, 'w')
1361595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  out_file.write(COPYRIGHT_HEADER)
13629edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  guard_name = 'TPM2_%s_' % _OUTPUT_FILE_H.upper().replace('.', '_')
1363595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  out_file.write(HEADER_FILE_GUARD_HEADER % {'name': guard_name})
13649edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  out_file.write(_HEADER_FILE_INCLUDES)
13659edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # These types are built-in or defined by <stdint.h>; they serve as base cases
13669edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # when defining type dependencies.
13679edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  declared_types = set(_BASIC_TYPES)
13689edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  # Generate serialize / parse function declarations.
13699edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  for basic_type in _BASIC_TYPES:
13709edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(_STANDARD_MARSHAL_DECLARATION % {'type': basic_type})
13713cd8526c535baca0947adccb82f8ef71cb45ba4cVadim Bendebury  for tpm_type in [typemap[x] for x in sorted(typemap.keys())]:
13729edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    tpm_type.OutputMarshalDecl(out_file, declared_types, typemap)
1373595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  out_file.write(HEADER_FILE_GUARD_FOOTER % {'name': guard_name})
13749edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  out_file.close()
13759edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  call(['clang-format', '-i', '-style=Chromium', 'tpm_generated.h'])
13769edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
13779edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
13783cd8526c535baca0947adccb82f8ef71cb45ba4cVadim Bendeburydef GenerateImplementation(typemap):
13799edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """Generates implementation code for each type.
13809edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer
13819edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  Args:
1382595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury    typemap: A dict mapping string type names to the corresponding object.
13839edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  """
13849edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  out_file = open(_OUTPUT_FILE_CC, 'w')
1385595736f2120e594839d6e73cb8245d8d7e5c2360Vadim Bendebury  out_file.write(COPYRIGHT_HEADER)
13869edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  out_file.write(_IMPLEMENTATION_FILE_INCLUDES)
13879edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  marshalled_types = set(_BASIC_TYPES)
13889edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  for basic_type in _BASIC_TYPES:
13899edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    out_file.write(_MARSHAL_BASIC_TYPE % {'type': basic_type})
13903cd8526c535baca0947adccb82f8ef71cb45ba4cVadim Bendebury  for tpm_type in [typemap[x] for x in sorted(typemap.keys())]:
13919edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer    tpm_type.OutputMarshalImpl(out_file, marshalled_types, typemap)
13929edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  out_file.close()
13939edfbac6a36e07e1a7ccb2260b6f65d97b45fef8ChromeOS Developer  call(['clang-format', '-i', '-style=Chromium', 'tpm_generated.c'])
1394