jabberd2  2.3.4
serial.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 /* these are useful utilities for data serialisation */
22 
23 #include "util.h"
24 
25 /*
26  * ser_string_get() and ser_int_get() retrieve a string (null-terminated) or
27  * an int (sizeof(int) chars) from source, and store it in dest. source is a
28  * pointer into buf, and will be updated before the call returns.
29  * buf is a pointer to the start of the source buffer, and len is the length
30  * of the buffer. if retrieving the data would take us pass the end of the
31  * array, a non-zero value will be returned. if the call succeeds, 0 is
32  * returned.
33  */
34 
35 int ser_string_get(char **dest, int *source, const char *buf, int len)
36 {
37  const char *end, *c;
38 
39  /* end of the buffer */
40  end = buf + ((sizeof(char) * (len - 1)));
41 
42  /* make sure we have a \0 before the end of the buffer */
43  c = &(buf[*source]);
44  while(c <= end && *c != '\0') c++;
45  if(c > end)
46  /* we ran past the end, fail */
47  return 1;
48 
49  /* copy the string */
50  *dest = strdup(&(buf[*source]));
51 
52  /* and move the pointer */
53  *source += strlen(*dest) + 1;
54 
55  return 0;
56 }
57 
58 int ser_int_get(int *dest, int *source, const char *buf, int len)
59 {
60  union
61  {
62  char c[sizeof(int)];
63  int i;
64  } u;
65  int i;
66 
67  /* we need sizeof(int) bytes */
68  if(&(buf[*source]) + sizeof(int) > buf + (sizeof(char) * len))
69  return 1;
70 
71  /* copy the bytes into the union. we do it this way to avoid alignment problems */
72  for(i = 0; i < sizeof(int); i++)
73  {
74  u.c[i] = buf[*source];
75  (*source)++;
76  }
77  *dest = u.i;
78 
79  return 0;
80 }
81 
82 /*
83  * ser_string_set() and ser_int_set() stores the string or int referenced by
84  * source into buf, starting at dest. len holds the current length of the
85  * buffer. if storing the data would overrun the end of the buffer, the buffer
86  * will be grown to accomodate. buf, dest and len will be updated.
87  */
88 
89 /* shamelessy stolen from nad.c */
90 
91 #define BLOCKSIZE 1024
92 
94 static int _ser_realloc(void **oblocks, int len)
95 {
96  void *nblocks;
97  int nlen;
98 
99  /* round up to standard block sizes */
100  nlen = (((len-1)/BLOCKSIZE)+1)*BLOCKSIZE;
101 
102  /* keep trying till we get it */
103  while((nblocks = realloc(*oblocks, nlen)) == NULL) sleep(1);
104  *oblocks = nblocks;
105  return nlen;
106 }
107 
109 #define SER_SAFE(blocks, size, len) if((size) > len) len = _ser_realloc((void**)&(blocks),(size));
110 
111 void ser_string_set(const char *source, int *dest, char **buf, int *len)
112 {
113  int need = sizeof(char) * (strlen(source) + 1);
114 
115  /* make more space if necessary */
116  SER_SAFE(*buf, *dest + need, *len);
117 
118  /* copy it in */
119  strcpy(*buf + *dest, source);
120 
121  /* and shift the pointer */
122  *dest += need;
123 }
124 
125 void ser_int_set(int source, int *dest, char **buf, int *len)
126 {
127  union
128  {
129  char c[sizeof(int)];
130  int i;
131  } u;
132  int i;
133 
134  /* make more space if necessary */
135  SER_SAFE(*buf, *dest + sizeof(int), *len)
136 
137  /* copy it in */
138  u.i = source;
139  for(i = 0; i < sizeof(int); i++)
140  (*buf)[*dest + i] = u.c[i];
141 
142  /* and shift the pointer */
143  *dest += sizeof(int);
144 }
int ser_int_get(int *dest, int *source, const char *buf, int len)
Definition: serial.c:58
static int _ser_realloc(void **oblocks, int len)
internal: do and return the math and ensure it gets realloc'd
Definition: serial.c:94
void ser_int_set(int source, int *dest, char **buf, int *len)
Definition: serial.c:125
#define BLOCKSIZE
Definition: serial.c:91
void ser_string_set(const char *source, int *dest, char **buf, int *len)
Definition: serial.c:111
#define SER_SAFE(blocks, size, len)
this is the safety check used to make sure there's always enough mem
Definition: serial.c:109
int ser_string_get(char **dest, int *source, const char *buf, int len)
Definition: serial.c:35