blob: f55a410290e4c38d777b91d643886605d447833e [file] [log] [blame]
Aleksander Morgado2a511da2012-05-30 12:40:46 +02001#!/usr/bin/env python
2# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3#
4# This program is free software; you can redistribute it and/or modify it under
5# the terms of the GNU Lesser General Public License as published by the Free
6# Software Foundation; either version 2 of the License, or (at your option) any
7# later version.
8#
9# This program is distributed in the hope that it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12# details.
13#
14# You should have received a copy of the GNU Lesser General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 51
16# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17#
18# Copyright (C) 2012 Lanedo GmbH
19#
20
21import string
22import utils
23from Variable import Variable
24
25"""
26Variable type for Strings ('string' format)
27"""
28class VariableString(Variable):
29
30 """
31 Constructor
32 """
33 def __init__(self, dictionary):
34
35 # Call the parent constructor
36 Variable.__init__(self, dictionary)
37
38 self.private_format = 'gchar *'
39 self.public_format = self.private_format
40
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +020041 if 'fixed-size' in dictionary:
42 self.is_fixed_size = True
43 # Fixed-size strings
44 self.needs_dispose = False
45 self.length_prefix = False
46 self.fixed_size = dictionary['fixed-size']
47 else:
48 self.is_fixed_size = False
49 # Variable-length strings in heap
50 self.needs_dispose = True
51 # Strings which are given as the full value of a TLV will NOT have a
52 # length prefix
53 self.length_prefix = False if 'type' in dictionary and dictionary['type'] == 'TLV' else True
54 self.fixed_size = ''
Aleksander Morgado2a511da2012-05-30 12:40:46 +020055
56
57 """
58 Read a string from the raw byte buffer.
59 """
60 def emit_buffer_read(self, f, line_prefix, variable_name, buffer_name, buffer_len):
61 translations = { 'lp' : line_prefix,
62 'variable_name' : variable_name,
63 'buffer_name' : buffer_name,
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +020064 'buffer_len' : buffer_len }
Aleksander Morgado2a511da2012-05-30 12:40:46 +020065
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +020066 if self.is_fixed_size:
67 translations['fixed_size'] = self.fixed_size
68 template = (
69 '${lp}/* Read the fixed-size string variable from the buffer */\n'
70 '${lp}qmi_utils_read_fixed_size_string_from_buffer (\n'
71 '${lp} &${buffer_name},\n'
72 '${lp} &${buffer_len},\n'
73 '${lp} ${fixed_size},\n'
74 '${lp} &${variable_name}[0]);\n'
75 '${lp}${variable_name}[${fixed_size}] = \'\\0\';\n')
76 else:
77 translations['length_prefix'] = 'TRUE' if self.length_prefix else 'FALSE'
78 template = (
79 '${lp}/* Read the string variable from the buffer */\n'
80 '${lp}qmi_utils_read_string_from_buffer (\n'
81 '${lp} &${buffer_name},\n'
82 '${lp} &${buffer_len},\n'
83 '${lp} ${length_prefix},\n'
84 '${lp} &(${variable_name}));\n')
85
Aleksander Morgado2a511da2012-05-30 12:40:46 +020086 f.write(string.Template(template).substitute(translations))
87
88
89 """
90 Write a string to the raw byte buffer.
91 """
92 def emit_buffer_write(self, f, line_prefix, variable_name, buffer_name, buffer_len):
93 translations = { 'lp' : line_prefix,
94 'variable_name' : variable_name,
95 'buffer_name' : buffer_name,
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +020096 'buffer_len' : buffer_len }
Aleksander Morgado2a511da2012-05-30 12:40:46 +020097
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +020098 if self.is_fixed_size:
99 translations['fixed_size'] = self.fixed_size
100 template = (
101 '${lp}/* Write the fixed-size string variable to the buffer */\n'
102 '${lp}qmi_utils_write_fixed_size_string_to_buffer (\n'
103 '${lp} &${buffer_name},\n'
104 '${lp} &${buffer_len},\n'
105 '${lp} ${fixed_size},\n'
106 '${lp} ${variable_name});\n')
107 else:
108 translations['length_prefix'] = 'TRUE' if self.length_prefix else 'FALSE'
109 template = (
110 '${lp}/* Write the string variable to the buffer */\n'
111 '${lp}qmi_utils_write_string_to_buffer (\n'
112 '${lp} &${buffer_name},\n'
113 '${lp} &${buffer_len},\n'
114 '${lp} ${length_prefix},\n'
115 '${lp} ${variable_name});\n')
116
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200117 f.write(string.Template(template).substitute(translations))
118
119
120 """
121 Get the string as printable
122 """
123 def emit_get_printable(self, f, line_prefix, printable, buffer_name, buffer_len):
124 translations = { 'lp' : line_prefix,
125 'printable' : printable,
126 'buffer_name' : buffer_name,
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200127 'buffer_len' : buffer_len }
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200128
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200129 if self.is_fixed_size:
130 translations['fixed_size'] = self.fixed_size
131 translations['fixed_size_plus_one'] = int(self.fixed_size) + 1
132 template = (
133 '\n'
134 '${lp}{\n'
135 '${lp} gchar tmp[${fixed_size_plus_one}];\n'
136 '\n'
137 '${lp} /* Read the fixed-size string variable from the buffer */\n'
138 '${lp} qmi_utils_read_fixed_size_string_from_buffer (\n'
139 '${lp} &${buffer_name},\n'
140 '${lp} &${buffer_len},\n'
141 '${lp} ${fixed_size},\n'
142 '${lp} &tmp[0]);\n'
143 '${lp} tmp[${fixed_size}] = \'\\0\';\n'
144 '\n'
145 '${lp} g_string_append_printf (${printable}, "%s", tmp);\n'
146 '${lp}}\n')
147 else:
148 translations['length_prefix'] = 'TRUE' if self.length_prefix else 'FALSE'
149 template = (
150 '\n'
151 '${lp}{\n'
152 '${lp} gchar *tmp;\n'
153 '\n'
154 '${lp} /* Read the string variable from the buffer */\n'
155 '${lp} qmi_utils_read_string_from_buffer (\n'
156 '${lp} &${buffer_name},\n'
157 '${lp} &${buffer_len},\n'
158 '${lp} ${length_prefix},\n'
159 '${lp} &tmp);\n'
160 '\n'
161 '${lp} g_string_append_printf (${printable}, "%s", tmp);\n'
162 '${lp} g_free (tmp);\n'
163 '${lp}}\n')
164
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200165 f.write(string.Template(template).substitute(translations))
166
167
168 """
Aleksander Morgado4130a722012-07-03 13:58:52 +0200169 Variable declaration
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200170 """
Aleksander Morgado4130a722012-07-03 13:58:52 +0200171 def build_variable_declaration(self, line_prefix, variable_name):
172 translations = { 'lp' : line_prefix,
173 'name' : variable_name }
174
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200175 if self.is_fixed_size:
176 translations['fixed_size_plus_one'] = int(self.fixed_size) + 1
177 template = (
178 '${lp}gchar ${name}[${fixed_size_plus_one}];\n')
179 else:
180 template = (
181 '${lp}gchar *${name};\n')
Aleksander Morgado4130a722012-07-03 13:58:52 +0200182 return string.Template(template).substitute(translations)
183
184
185 """
186 Getter for the string type
187 """
188 def build_getter_declaration(self, line_prefix, variable_name):
189 translations = { 'lp' : line_prefix,
190 'name' : variable_name }
191
192 template = (
193 '${lp}const gchar **${name},\n')
194 return string.Template(template).substitute(translations)
195
196
197 """
198 Documentation for the getter
199 """
200 def build_getter_documentation(self, line_prefix, variable_name):
201 translations = { 'lp' : line_prefix,
202 'name' : variable_name }
203
204 template = (
205 '${lp}@${name}: a placeholder for the output constant string, or #NULL if not required.\n')
206 return string.Template(template).substitute(translations)
207
208
209 """
210 Builds the String getter implementation
211 """
212 def build_getter_implementation(self, line_prefix, variable_name_from, variable_name_to, to_is_reference):
213 translations = { 'lp' : line_prefix,
214 'from' : variable_name_from,
215 'to' : variable_name_to }
216
217 if to_is_reference:
218 template = (
219 '${lp}if (${to})\n'
220 '${lp} *${to} = ${from};\n')
221 return string.Template(template).substitute(translations)
222 else:
223 template = (
224 '${lp}${to} = ${from};\n')
225 return string.Template(template).substitute(translations)
226
227
228 """
229 Setter for the string type
230 """
231 def build_setter_declaration(self, line_prefix, variable_name):
232 translations = { 'lp' : line_prefix,
233 'name' : variable_name }
234
235 template = (
236 '${lp}const gchar *${name},\n')
237 return string.Template(template).substitute(translations)
238
239
240 """
241 Documentation for the setter
242 """
243 def build_setter_documentation(self, line_prefix, variable_name):
244 translations = { 'lp' : line_prefix,
245 'name' : variable_name }
246
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200247 if self.is_fixed_size:
248 translations['fixed_size'] = self.fixed_size
249 template = (
250 '${lp}@${name}: a constant string of exactly ${fixed_size} characters.\n')
251 else:
252 template = (
253 '${lp}@${name}: a constant string.\n')
Aleksander Morgado4130a722012-07-03 13:58:52 +0200254 return string.Template(template).substitute(translations)
255
256
257 """
258 Builds the String setter implementation
259 """
260 def build_setter_implementation(self, line_prefix, variable_name_from, variable_name_to):
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200261 translations = { 'lp' : line_prefix,
262 'from' : variable_name_from,
263 'to' : variable_name_to }
264
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200265 if self.is_fixed_size:
266 translations['fixed_size'] = self.fixed_size
267 template = (
268 '${lp}if (!${from} || strlen (${from}) != ${fixed_size}) {\n'
269 '${lp} g_set_error (error,\n'
270 '${lp} QMI_CORE_ERROR,\n'
271 '${lp} QMI_CORE_ERROR_INVALID_ARGS,\n'
272 '${lp} "Input variable \'${from}\' must be ${fixed_size} characters long");\n'
273 '${lp} return FALSE;\n'
274 '${lp}}\n'
275 '${lp}memcpy (${to}, ${from}, ${fixed_size});\n'
276 '${lp}${to}[${fixed_size}] = \'\\0\';\n')
277 else:
278 template = (
279 '${lp}g_free (${to});\n'
280 '${lp}${to} = g_strdup (${from} ? ${from} : "");\n')
281
Aleksander Morgado4130a722012-07-03 13:58:52 +0200282 return string.Template(template).substitute(translations)
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200283
284
285 """
286 Dispose the string
287 """
Aleksander Morgado4130a722012-07-03 13:58:52 +0200288 def build_dispose(self, line_prefix, variable_name):
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200289 # Fixed-size strings don't need dispose
290 if self.is_fixed_size:
291 return ''
292
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200293 translations = { 'lp' : line_prefix,
294 'variable_name' : variable_name }
295
296 template = (
297 '${lp}g_free (${variable_name});\n')
Aleksander Morgado4130a722012-07-03 13:58:52 +0200298 return string.Template(template).substitute(translations)