blob: e4db6c62ee97da6a3b7999908a4152398b7e8172 [file] [log] [blame] [edit]
# -*- 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 [ <C type>, <is array>, <element size in bits> ]
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]