syslog-ng source
serialize.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002-2010 Balabit
3  * Copyright (c) 1998-2010 Balázs Scheidler
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * As an additional exemption you are allowed to compile & link against the
20  * OpenSSL libraries as published by the OpenSSL project. See the file
21  * COPYING for details.
22  *
23  */
24 
25 #ifndef SERIALIZE_H_INCLUDED
26 #define SERIALIZE_H_INCLUDED
27 
28 #include "syslog-ng.h"
29 
30 #include <stdio.h>
31 #include <string.h>
32 
33 typedef struct _SerializeArchive SerializeArchive;
34 
36 {
37  GError *error;
38  guint16 len;
39  guint16 silent: 1;
40 
41  gboolean (*read_bytes)(SerializeArchive *archive, gchar *buf, gsize count, GError **error);
42  gboolean (*write_bytes)(SerializeArchive *archive, const gchar *buf, gsize count, GError **error);
43 };
44 
45 /* this is private and is only published so that the inline functions below can invoke it */
46 void _serialize_handle_errors(SerializeArchive *self, const gchar *error_desc, GError *error);
47 
48 static inline gboolean
49 serialize_archive_read_bytes(SerializeArchive *self, gchar *buf, gsize buflen)
50 {
51  GError *error = NULL;
52 
53  if ((self->error == NULL) && !self->read_bytes(self, buf, buflen, &error))
54  _serialize_handle_errors(self, "Error reading serialized data", error);
55  return self->error == NULL;
56 }
57 
58 static inline gboolean
59 serialize_archive_write_bytes(SerializeArchive *self, const gchar *buf, gsize buflen)
60 {
61  GError *error = NULL;
62 
63  if ((self->error == NULL) && !self->write_bytes(self, buf, buflen, &error))
64  _serialize_handle_errors(self, "Error writing serialized data", error);
65  return self->error == NULL;
66 }
67 
68 static inline gboolean
69 serialize_write_uint32(SerializeArchive *archive, guint32 value)
70 {
71  guint32 n = GUINT32_TO_BE(value);
72  return serialize_archive_write_bytes(archive, (gchar *) &n, sizeof(n));
73 }
74 
75 static inline gboolean
76 serialize_read_uint32(SerializeArchive *archive, guint32 *value)
77 {
78  guint32 n;
79 
80  if (serialize_archive_read_bytes(archive, (gchar *) &n, sizeof(n)))
81  {
82  *value = GUINT32_FROM_BE(n);
83  return TRUE;
84  }
85  return FALSE;
86 }
87 
88 /* NOTE: this function writes to the array to convert it to big endian. It
89  * is converted back to native byte order before returning */
90 static inline gboolean
91 serialize_write_uint32_array(SerializeArchive *archive, guint32 *values, gsize elements)
92 {
93 #define BUFFER_SIZE 128
94  guint32 converted_values[BUFFER_SIZE];
95  gsize converted_ndx;
96 
97  while (elements > 0)
98  {
99  for (converted_ndx = 0;
100  converted_ndx < BUFFER_SIZE && converted_ndx < elements;
101  converted_ndx++)
102  converted_values[converted_ndx] = GUINT32_TO_BE(values[converted_ndx]);
103 
104  if (!serialize_archive_write_bytes(archive, (const gchar *) converted_values, converted_ndx * sizeof(guint32)))
105  return FALSE;
106 
107  values += converted_ndx;
108  elements -= converted_ndx;
109  }
110  return TRUE;
111 }
112 
113 static inline gboolean
114 serialize_read_uint32_array(SerializeArchive *archive, guint32 *values, gsize elements)
115 {
116  if (serialize_archive_read_bytes(archive, (gchar *) values, elements * sizeof(guint32)))
117  {
118  for (gsize i = 0; i < elements; i++)
119  values[i] = GUINT32_FROM_BE(values[i]);
120  return TRUE;
121  }
122  return FALSE;
123 }
124 
125 static inline gboolean
126 serialize_read_uint16_array(SerializeArchive *archive, guint32 *values, gsize elements)
127 {
128  gboolean ret = FALSE;
129  guint16 *buffer = g_new(guint16, elements);
130 
131  if (serialize_archive_read_bytes(archive, (gchar *) buffer, elements * sizeof(guint16)))
132  {
133  for (gsize i = 0; i < elements; i++)
134  values[i] = GUINT16_FROM_BE(buffer[i]);
135  ret = TRUE;
136  }
137  g_free(buffer);
138  return ret;
139 }
140 
141 static inline gboolean
142 serialize_write_uint64(SerializeArchive *archive, guint64 value)
143 {
144  guint64 n = GUINT64_TO_BE(value);
145  return serialize_archive_write_bytes(archive, (gchar *) &n, sizeof(n));
146 }
147 
148 static inline gboolean
149 serialize_read_uint64(SerializeArchive *archive, guint64 *value)
150 {
151  guint64 n;
152 
153  if (serialize_archive_read_bytes(archive, (gchar *) &n, sizeof(n)))
154  {
155  *value = GUINT64_FROM_BE(n);
156  return TRUE;
157  }
158  return FALSE;
159 }
160 
161 static inline gboolean
162 serialize_write_uint16(SerializeArchive *archive, guint16 value)
163 {
164  guint16 n = GUINT16_TO_BE(value);
165  return serialize_archive_write_bytes(archive, (gchar *) &n, sizeof(n));
166 }
167 
168 static inline gboolean
169 serialize_read_uint16(SerializeArchive *archive, guint16 *value)
170 {
171  guint16 n;
172 
173  if (serialize_archive_read_bytes(archive, (gchar *) &n, sizeof(n)))
174  {
175  *value = GUINT16_FROM_BE(n);
176  return TRUE;
177  }
178  return FALSE;
179 }
180 
181 static inline gboolean
182 serialize_write_uint8(SerializeArchive *archive, guint8 value)
183 {
184  guint8 n = value;
185  return serialize_archive_write_bytes(archive, (gchar *) &n, sizeof(n));
186 }
187 
188 static inline gboolean
189 serialize_read_uint8(SerializeArchive *archive, guint8 *value)
190 {
191  guint8 n;
192 
193  if (serialize_archive_read_bytes(archive, (gchar *) &n, sizeof(n)))
194  {
195  *value = n;
196  return TRUE;
197  }
198  return FALSE;
199 }
200 
201 
202 static inline gboolean
203 serialize_write_blob(SerializeArchive *archive, const void *blob, gsize len)
204 {
205  return serialize_archive_write_bytes(archive, (const gchar *) blob, len);
206 }
207 
208 static inline gboolean
209 serialize_read_blob(SerializeArchive *archive, void *blob, gsize len)
210 {
211  return serialize_archive_read_bytes(archive, (gchar *) blob, len);
212 }
213 
214 static inline gboolean
215 serialize_write_string(SerializeArchive *archive, GString *str)
216 {
217  return serialize_write_uint32(archive, str->len) &&
218  serialize_archive_write_bytes(archive, str->str, str->len);
219 }
220 
221 static inline gboolean
222 serialize_read_string(SerializeArchive *archive, GString *str)
223 {
224  guint32 len;
225 
226  if (serialize_read_uint32(archive, &len))
227  {
228  if (len > str->allocated_len)
229  {
230  gchar *p;
231 
232  p = (gchar *) g_try_realloc(str->str, len + 1);
233  if (!p)
234  return FALSE;
235  str->str = p;
236  str->str[len] = 0;
237  str->len = len;
238  }
239  else
240  g_string_set_size(str, len);
241 
242  return serialize_archive_read_bytes(archive, str->str, len);
243  }
244  return FALSE;
245 }
246 
247 static inline gboolean
248 serialize_write_cstring(SerializeArchive *archive, const gchar *str, gssize len)
249 {
250  if (len < 0)
251  len = strlen(str);
252 
253  return serialize_write_uint32(archive, len) &&
254  (len == 0 || serialize_archive_write_bytes(archive, str, len));
255 }
256 
257 static inline gboolean
258 serialize_read_cstring(SerializeArchive *archive, gchar **str, gsize *str_len)
259 {
260  guint32 len;
261 
262  if (serialize_read_uint32(archive, &len))
263  {
264  *str = (gchar *) g_try_malloc(len + 1);
265 
266  if (!(*str))
267  return FALSE;
268  (*str)[len] = 0;
269  if (str_len)
270  *str_len = len;
271  return serialize_archive_read_bytes(archive, *str, len);
272  }
273  return FALSE;
274 }
275 
276 
277 SerializeArchive *serialize_file_archive_new(FILE *f);
278 SerializeArchive *serialize_string_archive_new(GString *str);
279 void serialize_string_archive_reset(SerializeArchive *sa);
280 SerializeArchive *serialize_buffer_archive_new(gchar *buff, gsize len);
281 gsize serialize_buffer_archive_get_pos(SerializeArchive *self);
282 void serialize_archive_free(SerializeArchive *self);
283 
284 #endif
#define self
Definition: rcptid.c:38
void serialize_string_archive_reset(SerializeArchive *sa)
Definition: serialize.c:128
SerializeArchive * serialize_file_archive_new(FILE *f)
Definition: serialize.c:116
#define BUFFER_SIZE
gsize serialize_buffer_archive_get_pos(SerializeArchive *self)
Definition: serialize.c:216
SerializeArchive * serialize_buffer_archive_new(gchar *buff, gsize len)
Definition: serialize.c:224
SerializeArchive * serialize_string_archive_new(GString *str)
Definition: serialize.c:169
void serialize_archive_free(SerializeArchive *self)
Definition: serialize.c:68
void _serialize_handle_errors(SerializeArchive *self, const gchar *error_desc, GError *error)
Definition: serialize.c:54
Definition: serialize.h:36
GError * error
Definition: serialize.h:37
guint16 silent
Definition: serialize.h:39
guint16 len
Definition: serialize.h:38
gboolean(* write_bytes)(SerializeArchive *archive, const gchar *buf, gsize count, GError **error)
Definition: serialize.h:42
gboolean(* read_bytes)(SerializeArchive *archive, gchar *buf, gsize count, GError **error)
Definition: serialize.h:41
GString * value
Definition: test_decode.c:28
GString * buffer
Definition: test_smart_multi_line.c:69
SerializeArchive * sa
Definition: test_timestamp_serialize.c:31