blob: 02f827b59903163afd3cffc4412fd9f486084079 [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']
Aleksander Morgado6ba2b612012-07-06 09:43:15 +020047 self.max_size = ''
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +020048 else:
49 self.is_fixed_size = False
50 # Variable-length strings in heap
51 self.needs_dispose = True
52 # Strings which are given as the full value of a TLV will NOT have a
53 # length prefix
54 self.length_prefix = False if 'type' in dictionary and dictionary['type'] == 'TLV' else True
55 self.fixed_size = ''
Aleksander Morgado6ba2b612012-07-06 09:43:15 +020056 self.max_size = dictionary['max-size'] if 'max-size' in dictionary else ''
Aleksander Morgado2a511da2012-05-30 12:40:46 +020057
58
59 """
60 Read a string from the raw byte buffer.
61 """
62 def emit_buffer_read(self, f, line_prefix, variable_name, buffer_name, buffer_len):
63 translations = { 'lp' : line_prefix,
64 'variable_name' : variable_name,
65 'buffer_name' : buffer_name,
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +020066 'buffer_len' : buffer_len }
Aleksander Morgado2a511da2012-05-30 12:40:46 +020067
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +020068 if self.is_fixed_size:
69 translations['fixed_size'] = self.fixed_size
70 template = (
71 '${lp}/* Read the fixed-size string variable from the buffer */\n'
72 '${lp}qmi_utils_read_fixed_size_string_from_buffer (\n'
73 '${lp} &${buffer_name},\n'
74 '${lp} &${buffer_len},\n'
75 '${lp} ${fixed_size},\n'
76 '${lp} &${variable_name}[0]);\n'
77 '${lp}${variable_name}[${fixed_size}] = \'\\0\';\n')
78 else:
79 translations['length_prefix'] = 'TRUE' if self.length_prefix else 'FALSE'
Aleksander Morgado334177e2012-09-04 14:17:39 +020080 translations['max_size'] = self.max_size if self.max_size != '' else '0'
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +020081 template = (
82 '${lp}/* Read the string variable from the buffer */\n'
83 '${lp}qmi_utils_read_string_from_buffer (\n'
84 '${lp} &${buffer_name},\n'
85 '${lp} &${buffer_len},\n'
86 '${lp} ${length_prefix},\n'
Aleksander Morgado334177e2012-09-04 14:17:39 +020087 '${lp} ${max_size},\n'
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +020088 '${lp} &(${variable_name}));\n')
89
Aleksander Morgado2a511da2012-05-30 12:40:46 +020090 f.write(string.Template(template).substitute(translations))
91
92
93 """
94 Write a string to the raw byte buffer.
95 """
96 def emit_buffer_write(self, f, line_prefix, variable_name, buffer_name, buffer_len):
97 translations = { 'lp' : line_prefix,
98 'variable_name' : variable_name,
99 'buffer_name' : buffer_name,
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200100 'buffer_len' : buffer_len }
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200101
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200102 if self.is_fixed_size:
103 translations['fixed_size'] = self.fixed_size
104 template = (
105 '${lp}/* Write the fixed-size string variable to the buffer */\n'
106 '${lp}qmi_utils_write_fixed_size_string_to_buffer (\n'
107 '${lp} &${buffer_name},\n'
108 '${lp} &${buffer_len},\n'
109 '${lp} ${fixed_size},\n'
110 '${lp} ${variable_name});\n')
111 else:
112 translations['length_prefix'] = 'TRUE' if self.length_prefix else 'FALSE'
113 template = (
114 '${lp}/* Write the string variable to the buffer */\n'
115 '${lp}qmi_utils_write_string_to_buffer (\n'
116 '${lp} &${buffer_name},\n'
117 '${lp} &${buffer_len},\n'
118 '${lp} ${length_prefix},\n'
119 '${lp} ${variable_name});\n')
120
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200121 f.write(string.Template(template).substitute(translations))
122
123
124 """
125 Get the string as printable
126 """
127 def emit_get_printable(self, f, line_prefix, printable, buffer_name, buffer_len):
128 translations = { 'lp' : line_prefix,
129 'printable' : printable,
130 'buffer_name' : buffer_name,
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200131 'buffer_len' : buffer_len }
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200132
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200133 if self.is_fixed_size:
134 translations['fixed_size'] = self.fixed_size
135 translations['fixed_size_plus_one'] = int(self.fixed_size) + 1
136 template = (
137 '\n'
138 '${lp}{\n'
139 '${lp} gchar tmp[${fixed_size_plus_one}];\n'
140 '\n'
141 '${lp} /* Read the fixed-size string variable from the buffer */\n'
142 '${lp} qmi_utils_read_fixed_size_string_from_buffer (\n'
143 '${lp} &${buffer_name},\n'
144 '${lp} &${buffer_len},\n'
145 '${lp} ${fixed_size},\n'
146 '${lp} &tmp[0]);\n'
147 '${lp} tmp[${fixed_size}] = \'\\0\';\n'
148 '\n'
149 '${lp} g_string_append_printf (${printable}, "%s", tmp);\n'
150 '${lp}}\n')
151 else:
152 translations['length_prefix'] = 'TRUE' if self.length_prefix else 'FALSE'
Aleksander Morgado334177e2012-09-04 14:17:39 +0200153 translations['max_size'] = self.max_size if self.max_size != '' else '0'
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200154 template = (
155 '\n'
156 '${lp}{\n'
157 '${lp} gchar *tmp;\n'
158 '\n'
159 '${lp} /* Read the string variable from the buffer */\n'
160 '${lp} qmi_utils_read_string_from_buffer (\n'
161 '${lp} &${buffer_name},\n'
162 '${lp} &${buffer_len},\n'
163 '${lp} ${length_prefix},\n'
Aleksander Morgado334177e2012-09-04 14:17:39 +0200164 '${lp} ${max_size},\n'
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200165 '${lp} &tmp);\n'
166 '\n'
167 '${lp} g_string_append_printf (${printable}, "%s", tmp);\n'
168 '${lp} g_free (tmp);\n'
169 '${lp}}\n')
170
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200171 f.write(string.Template(template).substitute(translations))
172
173
174 """
Aleksander Morgado4130a722012-07-03 13:58:52 +0200175 Variable declaration
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200176 """
Aleksander Morgado4130a722012-07-03 13:58:52 +0200177 def build_variable_declaration(self, line_prefix, variable_name):
178 translations = { 'lp' : line_prefix,
179 'name' : variable_name }
180
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200181 if self.is_fixed_size:
182 translations['fixed_size_plus_one'] = int(self.fixed_size) + 1
183 template = (
184 '${lp}gchar ${name}[${fixed_size_plus_one}];\n')
185 else:
186 template = (
187 '${lp}gchar *${name};\n')
Aleksander Morgado4130a722012-07-03 13:58:52 +0200188 return string.Template(template).substitute(translations)
189
190
191 """
192 Getter for the string type
193 """
194 def build_getter_declaration(self, line_prefix, variable_name):
195 translations = { 'lp' : line_prefix,
196 'name' : variable_name }
197
198 template = (
199 '${lp}const gchar **${name},\n')
200 return string.Template(template).substitute(translations)
201
202
203 """
204 Documentation for the getter
205 """
206 def build_getter_documentation(self, line_prefix, variable_name):
207 translations = { 'lp' : line_prefix,
208 'name' : variable_name }
209
210 template = (
211 '${lp}@${name}: a placeholder for the output constant string, or #NULL if not required.\n')
212 return string.Template(template).substitute(translations)
213
214
215 """
216 Builds the String getter implementation
217 """
218 def build_getter_implementation(self, line_prefix, variable_name_from, variable_name_to, to_is_reference):
219 translations = { 'lp' : line_prefix,
220 'from' : variable_name_from,
221 'to' : variable_name_to }
222
223 if to_is_reference:
224 template = (
225 '${lp}if (${to})\n'
226 '${lp} *${to} = ${from};\n')
227 return string.Template(template).substitute(translations)
228 else:
229 template = (
230 '${lp}${to} = ${from};\n')
231 return string.Template(template).substitute(translations)
232
233
234 """
235 Setter for the string type
236 """
237 def build_setter_declaration(self, line_prefix, variable_name):
238 translations = { 'lp' : line_prefix,
239 'name' : variable_name }
240
241 template = (
242 '${lp}const gchar *${name},\n')
243 return string.Template(template).substitute(translations)
244
245
246 """
247 Documentation for the setter
248 """
249 def build_setter_documentation(self, line_prefix, variable_name):
250 translations = { 'lp' : line_prefix,
251 'name' : variable_name }
252
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200253 if self.is_fixed_size:
254 translations['fixed_size'] = self.fixed_size
255 template = (
256 '${lp}@${name}: a constant string of exactly ${fixed_size} characters.\n')
Aleksander Morgado6ba2b612012-07-06 09:43:15 +0200257 elif self.max_size != '':
258 translations['max_size'] = self.max_size
259 template = (
260 '${lp}@${name}: a constant string with a maximum length of ${max_size} characters.\n')
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200261 else:
262 template = (
263 '${lp}@${name}: a constant string.\n')
Aleksander Morgado4130a722012-07-03 13:58:52 +0200264 return string.Template(template).substitute(translations)
265
266
267 """
268 Builds the String setter implementation
269 """
270 def build_setter_implementation(self, line_prefix, variable_name_from, variable_name_to):
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200271 translations = { 'lp' : line_prefix,
272 'from' : variable_name_from,
273 'to' : variable_name_to }
274
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200275 if self.is_fixed_size:
276 translations['fixed_size'] = self.fixed_size
277 template = (
278 '${lp}if (!${from} || strlen (${from}) != ${fixed_size}) {\n'
279 '${lp} g_set_error (error,\n'
280 '${lp} QMI_CORE_ERROR,\n'
281 '${lp} QMI_CORE_ERROR_INVALID_ARGS,\n'
282 '${lp} "Input variable \'${from}\' must be ${fixed_size} characters long");\n'
283 '${lp} return FALSE;\n'
284 '${lp}}\n'
285 '${lp}memcpy (${to}, ${from}, ${fixed_size});\n'
286 '${lp}${to}[${fixed_size}] = \'\\0\';\n')
287 else:
Aleksander Morgado6ba2b612012-07-06 09:43:15 +0200288 template = ''
289 if self.max_size != '':
290 translations['max_size'] = self.max_size
291 template += (
292 '${lp}if (${from} && strlen (${from}) > ${max_size}) {\n'
293 '${lp} g_set_error (error,\n'
294 '${lp} QMI_CORE_ERROR,\n'
295 '${lp} QMI_CORE_ERROR_INVALID_ARGS,\n'
296 '${lp} "Input variable \'${from}\' must be less than ${max_size} characters long");\n'
297 '${lp} return FALSE;\n'
298 '${lp}}\n')
299 template += (
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200300 '${lp}g_free (${to});\n'
301 '${lp}${to} = g_strdup (${from} ? ${from} : "");\n')
302
Aleksander Morgado4130a722012-07-03 13:58:52 +0200303 return string.Template(template).substitute(translations)
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200304
305
306 """
307 Dispose the string
308 """
Aleksander Morgado4130a722012-07-03 13:58:52 +0200309 def build_dispose(self, line_prefix, variable_name):
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200310 # Fixed-size strings don't need dispose
311 if self.is_fixed_size:
312 return ''
313
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200314 translations = { 'lp' : line_prefix,
315 'variable_name' : variable_name }
316
317 template = (
318 '${lp}g_free (${variable_name});\n')
Aleksander Morgado4130a722012-07-03 13:58:52 +0200319 return string.Template(template).substitute(translations)