From ec222517eef73cfe1b1b6367935638073036be55 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Tue, 3 Jul 2012 14:01:56 +0200 Subject: qmi-codegen: new `sequence' variable type The `sequence' variable types are defined in the same way as `struct' types, but the generated implementation is completely different: * Struct TLVs will generate public struct types, and the getter/setter methods will pass a single variable of that new struct type. * Sequence TLVs will not generate any new public nor private type. The getter and setter methods will pass N items, one for each member of the sequence. It should be safe to do so and maintain API/ABI compatibility afterwards, as existing TLVs are not expected to change. --- build-aux/qmi-codegen/Makefile.am | 1 + build-aux/qmi-codegen/VariableFactory.py | 3 + build-aux/qmi-codegen/VariableSequence.py | 195 ++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 build-aux/qmi-codegen/VariableSequence.py diff --git a/build-aux/qmi-codegen/Makefile.am b/build-aux/qmi-codegen/Makefile.am index d1682f7..aa2a14a 100644 --- a/build-aux/qmi-codegen/Makefile.am +++ b/build-aux/qmi-codegen/Makefile.am @@ -11,6 +11,7 @@ EXTRA_DIST = \ VariableFactory.py \ VariableArray.py \ VariableStruct.py \ + VariableSequence.py \ VariableInteger.py \ VariableString.py \ utils.py \ diff --git a/build-aux/qmi-codegen/VariableFactory.py b/build-aux/qmi-codegen/VariableFactory.py index e8d9ba4..e1d5c95 100644 --- a/build-aux/qmi-codegen/VariableFactory.py +++ b/build-aux/qmi-codegen/VariableFactory.py @@ -22,6 +22,7 @@ import utils from VariableInteger import VariableInteger from VariableString import VariableString from VariableStruct import VariableStruct +from VariableSequence import VariableSequence from VariableArray import VariableArray @@ -36,6 +37,8 @@ def create_variable(dictionary, new_type_name): return VariableString(dictionary) elif dictionary['format'] == 'struct': return VariableStruct(dictionary, new_type_name) + elif dictionary['format'] == 'sequence': + return VariableSequence(dictionary, new_type_name) elif dictionary['format'] == 'array': return VariableArray(dictionary, new_type_name) else: diff --git a/build-aux/qmi-codegen/VariableSequence.py b/build-aux/qmi-codegen/VariableSequence.py new file mode 100644 index 0000000..9436ea0 --- /dev/null +++ b/build-aux/qmi-codegen/VariableSequence.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python +# -*- 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 Lesser General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) any +# later version. +# +# 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 Lesser General Public License for more +# details. +# +# You should have received a copy of the GNU Lesser 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) 2012 Lanedo GmbH +# + +import string +import utils +from Variable import Variable +import VariableFactory + +""" +Variable type for Sequences ('sequence' format) +""" +class VariableSequence(Variable): + + """ + Constructor + """ + def __init__(self, dictionary, sequence_type_name): + + # Call the parent constructor + Variable.__init__(self, dictionary) + + # Load members of this sequence + self.members = [] + for member_dictionary in dictionary['contents']: + member = {} + member['name'] = utils.build_underscore_name(member_dictionary['name']) + member['object'] = VariableFactory.create_variable(member_dictionary, sequence_type_name + ' ' + member['name']) + self.members.append(member) + + # TODO: do we need this? + # We'll need to dispose if at least one of the members needs it + for member in self.members: + if member['object'].needs_dispose == True: + self.needs_dispose = True + + + """ + Emit all types for the members of the sequence + """ + def emit_types(self, f): + # Emit types for each member + for member in self.members: + member['object'].emit_types(f) + + + """ + Reading the contents of a sequence is just about reading each of the sequence + fields one by one. + """ + def emit_buffer_read(self, f, line_prefix, variable_name, buffer_name, buffer_len): + for member in self.members: + member['object'].emit_buffer_read(f, line_prefix, variable_name + '_' + member['name'], buffer_name, buffer_len) + + + """ + Writing the contents of a sequence is just about writing each of the sequence + fields one by one. + """ + def emit_buffer_write(self, f, line_prefix, variable_name, buffer_name, buffer_len): + for member in self.members: + member['object'].emit_buffer_write(f, line_prefix, variable_name + '_' + member['name'], buffer_name, buffer_len) + + + """ + The sequence will be printed as a list of fields enclosed between square + brackets + """ + def emit_get_printable(self, f, line_prefix, printable, buffer_name, buffer_len): + translations = { 'lp' : line_prefix, + 'printable' : printable } + + template = ( + '${lp}g_string_append (${printable}, "[");\n') + f.write(string.Template(template).substitute(translations)) + + for member in self.members: + translations['variable_name'] = member['name'] + template = ( + '${lp}g_string_append (${printable}, " ${variable_name} = \'");\n') + f.write(string.Template(template).substitute(translations)) + + member['object'].emit_get_printable(f, line_prefix, printable, buffer_name, buffer_len) + + template = ( + '${lp}g_string_append (${printable}, "\'");\n') + f.write(string.Template(template).substitute(translations)) + + template = ( + '${lp}g_string_append (${printable}, " ]");\n') + f.write(string.Template(template).substitute(translations)) + + + """ + Variable declaration + """ + def build_variable_declaration(self, line_prefix, variable_name): + built = '' + for member in self.members: + built += member['object'].build_variable_declaration(line_prefix, variable_name + '_' + member['name']) + return built + + + """ + The getter for a sequence variable will include independent getters for each + of the variables in the sequence. + """ + def build_getter_declaration(self, line_prefix, variable_name): + built = '' + for member in self.members: + built += member['object'].build_getter_declaration(line_prefix, variable_name + '_' + member['name']) + return built + + + """ + Documentation for the getter + """ + def build_getter_documentation(self, line_prefix, variable_name): + built = '' + for member in self.members: + built += member['object'].build_getter_documentation(line_prefix, variable_name + '_' + member['name']) + return built + + + """ + Builds the Struct getter implementation + """ + def build_getter_implementation(self, line_prefix, variable_name_from, variable_name_to, to_is_reference): + built = '' + for member in self.members: + built += member['object'].build_getter_implementation(line_prefix, + variable_name_from + '_' + member['name'], + variable_name_to + '_' + member['name'], + to_is_reference) + return built + + + """ + The setter for a sequence variable will include independent setters for each + of the variables in the sequence. + """ + def build_setter_declaration(self, line_prefix, variable_name): + built = '' + for member in self.members: + built += member['object'].build_setter_declaration(line_prefix, variable_name + '_' + member['name']) + return built + + + """ + Documentation for the setter + """ + def build_setter_documentation(self, line_prefix, variable_name): + built = '' + for member in self.members: + built += member['object'].build_setter_documentation(line_prefix, variable_name + '_' + member['name']) + return built + + + """ + Builds the Sequence setter implementation + """ + def build_setter_implementation(self, line_prefix, variable_name_from, variable_name_to): + built = '' + for member in self.members: + built += member['object'].build_setter_implementation(line_prefix, + variable_name_from + '_' + member['name'], + variable_name_to + '_' + member['name']) + return built + + + """ + Disposing a sequence is just about disposing each of the sequence fields one by + one. + """ + def build_dispose(self, line_prefix, variable_name): + built = '' + for member in self.members: + built += member['object'].build_dispose(line_prefix, variable_name + '_' + member['name']) + return built -- cgit v1.2.3