# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation, version 2. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # details. # # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., 51 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # Copyright (C) 2011 - 2012 Red Hat, Inc. # import utils # eDB2FieldType FIELD_TYPE_STD = 0 # Field is a standard type (see below) FIELD_TYPE_ENUM_UNSIGNED = 1 # Field is an unsigned enumerated type FIELD_TYPE_ENUM_SIGNED = 2 # Field is a signed enumerated type # eDB2StdFieldType FIELD_STD_BOOL = 0 # boolean (0/1, false/true) FIELD_STD_INT8 = 1 # 8-bit signed integer FIELD_STD_UINT8 = 2 # 8-bit unsigned integer FIELD_STD_INT16 = 3 # 16-bit signed integer FIELD_STD_UINT16 = 4 # 16-bit unsigned integer FIELD_STD_INT32 = 5 # 32-bit signed integer FIELD_STD_UINT32 = 6 # 32-bit unsigned integer FIELD_STD_INT64 = 7 # 64-bit signed integer FIELD_STD_UINT64 = 8 # 64-bit unsigned integer FIELD_STD_STRING_A = 9 # ANSI (ASCII?) fixed length string; size in bits FIELD_STD_STRING_U = 10 # UCS-2 fixed length string FIELD_STD_STRING_ANT = 11 # ANSI (ASCII?) NULL terminated string FIELD_STD_STRING_UNT = 12 # UCS-2 NULL terminated string FIELD_STD_FLOAT32 = 13 # 32-bit floating point value FIELD_STD_FLOAT64 = 14 # 64-bit floating point value FIELD_STD_STRING_U8 = 15 # UTF-8 encoded fixed length string FIELD_STD_STRING_U8NT = 16 # UTF-8 encoded NULL terminated string stdtypes = { # Maps field type to [ , , ] FIELD_STD_BOOL: [ 'bool', False, 8 ], FIELD_STD_INT8: [ 'int8', False, 8 ], FIELD_STD_UINT8: [ 'uint8', False, 8 ], FIELD_STD_INT16: [ 'int16', False, 16 ], FIELD_STD_UINT16: [ 'uint16', False, 16 ], FIELD_STD_INT32: [ 'int32', False, 32 ], FIELD_STD_UINT32: [ 'uint32', False, 32 ], FIELD_STD_INT64: [ 'int64', False, 64 ], FIELD_STD_UINT64: [ 'uint64', False, 64 ], FIELD_STD_STRING_A: [ 'char', True, 8 ], FIELD_STD_STRING_U: [ 'uint16', True, 16 ], FIELD_STD_STRING_ANT: [ 'char *', False, 8 ], FIELD_STD_STRING_UNT: [ 'char *', False, 8 ], FIELD_STD_FLOAT32: [ 'float32', False, 32 ], FIELD_STD_FLOAT64: [ 'float64', False, 64 ], } def is_array_type(t): return stdtypes[t][1] class Field: def __init__(self, line): parts = line.split('^') if len(parts) < 6: raise Exception("Invalid field line '%s'" % line) self.id = int(parts[0]) self.name = parts[1].replace('"', '') self.size = int(parts[2]) # in *bits* self.type = int(parts[3]) # eDB2FieldType self.typeval = int(parts[4]) # eDB2StdFieldType if 'type' == 0 self.hex = int(parts[5]) != 0 self.descid = None self.internal = False if len(parts) > 6: self.descid = int(parts[6]) if len(parts) > 7: self.internal = int(parts[7]) # Field.txt:50118^"IP V4 Address"^8^0^2^0 #Field.txt:50118^"IP V4 Address"^8^0^2^0 def get_charsize(self): if self.type == FIELD_TYPE_STD: if self.typeval == FIELD_STD_STRING_A or self.typeval == FIELD_STD_STRING_ANT or \ self.typeval == FIELD_STD_STRING_U or self.typeval == FIELD_STD_STRING_UNT: return stdtypes[self.typeval][2] raise Exception("Called for non-string type") def emit(self, do_print, indent, enums, num_elements, comment, isarray): ctype = '' arraypart = '' sizebits = 0 if self.type == FIELD_TYPE_STD: # eDB2_FIELD_STD tinfo = stdtypes[self.typeval] ctype = tinfo[0] if is_array_type(self.typeval) or num_elements > 0: if num_elements > 0: arraypart = "[%d]" % num_elements sizebits = num_elements * tinfo[2] elif isarray: # array with size given by previous fragment arraypart = "[0]" sizebits = 0 else: arraypart = "[%d]" % (self.size / tinfo[2]) sizebits = self.size * tinfo[2] elif self.type == FIELD_TYPE_ENUM_UNSIGNED or self.type == FIELD_TYPE_ENUM_SIGNED: # It's a enum; find the enum e = enums.get_child(self.typeval) ctype = "gobi_%s" % utils.nicename(e.name) if isarray: if num_elements != 0: raise Exception("Unhandled ENUM field type with size %d" % num_elements) arraypart = "[0]"; sizebits = 0 else: if self.size > 0: # enum size is # of bits arraypart = ":%d" % self.size sizebits = self.size else: sizebits = 32 else: raise ValueError("Unknown Field type") if comment: comment = " (%s)" % comment if do_print: print "%s%s %s%s; /* %s%s */" % ("\t" * indent, ctype, utils.nicename(self.name), arraypart, self.name, comment) return sizebits class Fields: def __init__(self, path): self.byid = {} f = file(path + "Field.txt") for line in f: field = Field(line.strip()) self.byid[field.id] = field def has_child(self, fid): return fid in self.byid def get_child(self, fid): return self.byid[fid]