4 * @brief Generic types.
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34 * String mappings for type status_t.
36 mapping_t status_m
[] = {
39 {OUT_OF_RES
, "OUT_OF_RES"},
40 {ALREADY_DONE
, "ALREADY_DONE"},
41 {NOT_SUPPORTED
, "NOT_SUPPORTED"},
42 {INVALID_ARG
, "INVALID_ARG"},
43 {NOT_FOUND
, "NOT_FOUND"},
44 {PARSE_ERROR
, "PARSE_ERROR"},
45 {VERIFY_ERROR
, "VERIFY_ERROR"},
46 {INVALID_STATE
, "INVALID_STATE"},
47 {DESTROY_ME
, "DESTROY_ME"},
54 chunk_t CHUNK_INITIALIZER
= { NULL
, 0 };
57 * Described in header.
59 chunk_t
chunk_clone(chunk_t chunk
)
61 chunk_t clone
= CHUNK_INITIALIZER
;
63 if (chunk
.ptr
&& chunk
.len
> 0)
65 clone
.ptr
= malloc(chunk
.len
);
66 clone
.len
= chunk
.len
;
67 memcpy(clone
.ptr
, chunk
.ptr
, chunk
.len
);
76 chunk_t
chunk_cat(const char* mode
, ...)
82 int count
= strlen(mode
);
84 /* sum up lengths of individual chunks */
85 va_start(chunks
, mode
);
87 for (i
= 0; i
< count
; i
++)
89 chunk_t ch
= va_arg(chunks
, chunk_t
);
90 construct
.len
+= ch
.len
;
94 /* allocate needed memory for construct */
95 construct
.ptr
= malloc(construct
.len
);
98 /* copy or move the chunks */
99 va_start(chunks
, mode
);
100 for (i
= 0; i
< count
; i
++)
102 chunk_t ch
= va_arg(chunks
, chunk_t
);
106 memcpy(pos
, ch
.ptr
, ch
.len
);
112 memcpy(pos
, ch
.ptr
, ch
.len
);
122 * Described in header.
124 void chunk_free(chunk_t
*chunk
)
132 * Described in header.
134 chunk_t
chunk_alloc(size_t bytes
)
137 new_chunk
.ptr
= malloc(bytes
);
138 new_chunk
.len
= bytes
;
143 * Described in header.
145 bool chunk_equals(chunk_t a
, chunk_t b
)
147 return a
.ptr
!= NULL
&& b
.ptr
!= NULL
&&
148 a
.len
== b
.len
&& memeq(a
.ptr
, b
.ptr
, a
.len
);
152 * Described in header.
154 bool chunk_equals_or_null(chunk_t a
, chunk_t b
)
156 if (a
.ptr
== NULL
|| b
.ptr
== NULL
)
158 return a
.len
== b
.len
&& memeq(a
.ptr
, b
.ptr
, a
.len
);
162 * Described in header.
164 void chunk_to_hex(char *buf
, size_t buflen
, chunk_t chunk
)
168 buflen
--; /* reserve space for null termination */
170 while (chunk
.len
> 0 && buflen
> 2)
172 static char hexdig
[] = "0123456789abcdef";
180 *buf
++ = ':'; buflen
--;
182 *buf
++ = hexdig
[(*chunk
.ptr
>> 4) & 0x0f];
183 *buf
++ = hexdig
[ *chunk
.ptr
++ & 0x0f];
184 buflen
-= 2; chunk
.len
--;
190 * Described in header.
192 void *clalloc(void * pointer
, size_t size
)
197 memcpy(data
, pointer
,size
);
203 * We use a single mutex for all refcount variables. This
204 * is not optimal for performance, but the critical section
205 * is not that long...
206 * TODO: Consider to include a mutex in each refcount_t variable.
208 static pthread_mutex_t ref_mutex
= PTHREAD_MUTEX_INITIALIZER
;
211 * Described in header.
213 * TODO: May be implemented with atomic CPU instructions
214 * instead of a mutex.
216 void ref_get(refcount_t
*ref
)
218 pthread_mutex_lock(&ref_mutex
);
220 pthread_mutex_unlock(&ref_mutex
);
224 * Described in header.
226 * TODO: May be implemented with atomic CPU instructions
227 * instead of a mutex.
229 bool ref_put(refcount_t
*ref
)
233 pthread_mutex_lock(&ref_mutex
);
234 more_refs
= --(*ref
);
235 pthread_mutex_unlock(&ref_mutex
);
240 * Names of the months used by timetoa()
242 static const char* months
[] = {
243 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
244 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
248 * Described in header file
250 void timetoa(char *buf
, size_t buflen
, const time_t *time
, bool utc
)
252 if (*time
== UNDEFINED_TIME
)
253 snprintf(buf
, buflen
, "--- -- --:--:--%s----", (utc
)?
" UTC ":" ");
256 struct tm
*t
= (utc
)?
gmtime(time
) : localtime(time
);
258 snprintf(buf
, buflen
, "%s %02d %02d:%02d:%02d%s%04d",
259 months
[t
->tm_mon
], t
->tm_mday
, t
->tm_hour
, t
->tm_min
, t
->tm_sec
,
260 (utc
)?
" UTC ":" ", t
->tm_year
+ 1900);