blob: c39602f1115c3e3fee02fa7ba2f449bf010a275f [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'
80 template = (
81 '${lp}/* Read the string variable from the buffer */\n'
82 '${lp}qmi_utils_read_string_from_buffer (\n'
83 '${lp} &${buffer_name},\n'
84 '${lp} &${buffer_len},\n'
85 '${lp} ${length_prefix},\n'
86 '${lp} &(${variable_name}));\n')
87
Aleksander Morgado2a511da2012-05-30 12:40:46 +020088 f.write(string.Template(template).substitute(translations))
89
90
91 """
92 Write a string to the raw byte buffer.
93 """
94 def emit_buffer_write(self, f, line_prefix, variable_name, buffer_name, buffer_len):
95 translations = { 'lp' : line_prefix,
96 'variable_name' : variable_name,
97 'buffer_name' : buffer_name,
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +020098 'buffer_len' : buffer_len }
Aleksander Morgado2a511da2012-05-30 12:40:46 +020099
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200100 if self.is_fixed_size:
101 translations['fixed_size'] = self.fixed_size
102 template = (
103 '${lp}/* Write the fixed-size string variable to the buffer */\n'
104 '${lp}qmi_utils_write_fixed_size_string_to_buffer (\n'
105 '${lp} &${buffer_name},\n'
106 '${lp} &${buffer_len},\n'
107 '${lp} ${fixed_size},\n'
108 '${lp} ${variable_name});\n')
109 else:
110 translations['length_prefix'] = 'TRUE' if self.length_prefix else 'FALSE'
111 template = (
112 '${lp}/* Write the string variable to the buffer */\n'
113 '${lp}qmi_utils_write_string_to_buffer (\n'
114 '${lp} &${buffer_name},\n'
115 '${lp} &${buffer_len},\n'
116 '${lp} ${length_prefix},\n'
117 '${lp} ${variable_name});\n')
118
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200119 f.write(string.Template(template).substitute(translations))
120
121
122 """
123 Get the string as printable
124 """
125 def emit_get_printable(self, f, line_prefix, printable, buffer_name, buffer_len):
126 translations = { 'lp' : line_prefix,
127 'printable' : printable,
128 'buffer_name' : buffer_name,
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200129 'buffer_len' : buffer_len }
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200130
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200131 if self.is_fixed_size:
132 translations['fixed_size'] = self.fixed_size
133 translations['fixed_size_plus_one'] = int(self.fixed_size) + 1
134 template = (
135 '\n'
136 '${lp}{\n'
137 '${lp} gchar tmp[${fixed_size_plus_one}];\n'
138 '\n'
139 '${lp} /* Read the fixed-size string variable from the buffer */\n'
140 '${lp} qmi_utils_read_fixed_size_string_from_buffer (\n'
141 '${lp} &${buffer_name},\n'
142 '${lp} &${buffer_len},\n'
143 '${lp} ${fixed_size},\n'
144 '${lp} &tmp[0]);\n'
145 '${lp} tmp[${fixed_size}] = \'\\0\';\n'
146 '\n'
147 '${lp} g_string_append_printf (${printable}, "%s", tmp);\n'
148 '${lp}}\n')
149 else:
150 translations['length_prefix'] = 'TRUE' if self.length_prefix else 'FALSE'
151 template = (
152 '\n'
153 '${lp}{\n'
154 '${lp} gchar *tmp;\n'
155 '\n'
156 '${lp} /* Read the string variable from the buffer */\n'
157 '${lp} qmi_utils_read_string_from_buffer (\n'
158 '${lp} &${buffer_name},\n'
159 '${lp} &${buffer_len},\n'
160 '${lp} ${length_prefix},\n'
161 '${lp} &tmp);\n'
162 '\n'
163 '${lp} g_string_append_printf (${printable}, "%s", tmp);\n'
164 '${lp} g_free (tmp);\n'
165 '${lp}}\n')
166
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200167 f.write(string.Template(template).substitute(translations))
168
169
170 """
Aleksander Morgado4130a722012-07-03 13:58:52 +0200171 Variable declaration
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200172 """
Aleksander Morgado4130a722012-07-03 13:58:52 +0200173 def build_variable_declaration(self, line_prefix, variable_name):
174 translations = { 'lp' : line_prefix,
175 'name' : variable_name }
176
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200177 if self.is_fixed_size:
178 translations['fixed_size_plus_one'] = int(self.fixed_size) + 1
179 template = (
180 '${lp}gchar ${name}[${fixed_size_plus_one}];\n')
181 else:
182 template = (
183 '${lp}gchar *${name};\n')
Aleksander Morgado4130a722012-07-03 13:58:52 +0200184 return string.Template(template).substitute(translations)
185
186
187 """
188 Getter for the string type
189 """
190 def build_getter_declaration(self, line_prefix, variable_name):
191 translations = { 'lp' : line_prefix,
192 'name' : variable_name }
193
194 template = (
195 '${lp}const gchar **${name},\n')
196 return string.Template(template).substitute(translations)
197
198
199 """
200 Documentation for the getter
201 """
202 def build_getter_documentation(self, line_prefix, variable_name):
203 translations = { 'lp' : line_prefix,
204 'name' : variable_name }
205
206 template = (
207 '${lp}@${name}: a placeholder for the output constant string, or #NULL if not required.\n')
208 return string.Template(template).substitute(translations)
209
210
211 """
212 Builds the String getter implementation
213 """
214 def build_getter_implementation(self, line_prefix, variable_name_from, variable_name_to, to_is_reference):
215 translations = { 'lp' : line_prefix,
216 'from' : variable_name_from,
217 'to' : variable_name_to }
218
219 if to_is_reference:
220 template = (
221 '${lp}if (${to})\n'
222 '${lp} *${to} = ${from};\n')
223 return string.Template(template).substitute(translations)
224 else:
225 template = (
226 '${lp}${to} = ${from};\n')
227 return string.Template(template).substitute(translations)
228
229
230 """
231 Setter for the string type
232 """
233 def build_setter_declaration(self, line_prefix, variable_name):
234 translations = { 'lp' : line_prefix,
235 'name' : variable_name }
236
237 template = (
238 '${lp}const gchar *${name},\n')
239 return string.Template(template).substitute(translations)
240
241
242 """
243 Documentation for the setter
244 """
245 def build_setter_documentation(self, line_prefix, variable_name):
246 translations = { 'lp' : line_prefix,
247 'name' : variable_name }
248
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200249 if self.is_fixed_size:
250 translations['fixed_size'] = self.fixed_size
251 template = (
252 '${lp}@${name}: a constant string of exactly ${fixed_size} characters.\n')
Aleksander Morgado6ba2b612012-07-06 09:43:15 +0200253 elif self.max_size != '':
254 translations['max_size'] = self.max_size
255 template = (
256 '${lp}@${name}: a constant string with a maximum length of ${max_size} characters.\n')
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200257 else:
258 template = (
259 '${lp}@${name}: a constant string.\n')
Aleksander Morgado4130a722012-07-03 13:58:52 +0200260 return string.Template(template).substitute(translations)
261
262
263 """
264 Builds the String setter implementation
265 """
266 def build_setter_implementation(self, line_prefix, variable_name_from, variable_name_to):
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200267 translations = { 'lp' : line_prefix,
268 'from' : variable_name_from,
269 'to' : variable_name_to }
270
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200271 if self.is_fixed_size:
272 translations['fixed_size'] = self.fixed_size
273 template = (
274 '${lp}if (!${from} || strlen (${from}) != ${fixed_size}) {\n'
275 '${lp} g_set_error (error,\n'
276 '${lp} QMI_CORE_ERROR,\n'
277 '${lp} QMI_CORE_ERROR_INVALID_ARGS,\n'
278 '${lp} "Input variable \'${from}\' must be ${fixed_size} characters long");\n'
279 '${lp} return FALSE;\n'
280 '${lp}}\n'
281 '${lp}memcpy (${to}, ${from}, ${fixed_size});\n'
282 '${lp}${to}[${fixed_size}] = \'\\0\';\n')
283 else:
Aleksander Morgado6ba2b612012-07-06 09:43:15 +0200284 template = ''
285 if self.max_size != '':
286 translations['max_size'] = self.max_size
287 template += (
288 '${lp}if (${from} && strlen (${from}) > ${max_size}) {\n'
289 '${lp} g_set_error (error,\n'
290 '${lp} QMI_CORE_ERROR,\n'
291 '${lp} QMI_CORE_ERROR_INVALID_ARGS,\n'
292 '${lp} "Input variable \'${from}\' must be less than ${max_size} characters long");\n'
293 '${lp} return FALSE;\n'
294 '${lp}}\n')
295 template += (
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200296 '${lp}g_free (${to});\n'
297 '${lp}${to} = g_strdup (${from} ? ${from} : "");\n')
298
Aleksander Morgado4130a722012-07-03 13:58:52 +0200299 return string.Template(template).substitute(translations)
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200300
301
302 """
303 Dispose the string
304 """
Aleksander Morgado4130a722012-07-03 13:58:52 +0200305 def build_dispose(self, line_prefix, variable_name):
Aleksander Morgadob3f6aab2012-07-06 08:43:49 +0200306 # Fixed-size strings don't need dispose
307 if self.is_fixed_size:
308 return ''
309
Aleksander Morgado2a511da2012-05-30 12:40:46 +0200310 translations = { 'lp' : line_prefix,
311 'variable_name' : variable_name }
312
313 template = (
314 '${lp}g_free (${variable_name});\n')
Aleksander Morgado4130a722012-07-03 13:58:52 +0200315 return string.Template(template).substitute(translations)