Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
tmpbuf.c
Go to the documentation of this file.
1/*
2 Tmpbuf - Round Robin Temporary buffers
3
4 Copyright (C)
5 2008, 2010 Christian Thaeter <ct@pipapo.org>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
14
23#include "lib/safeclib.h"
24#include "lib/tmpbuf.h"
25
26
27#include <string.h>
28#include <pthread.h>
29#include <stdint.h>
30#include <stdarg.h>
31#include <nobug.h>
32
33
34
36{
37 void* buffers[64];
38 size_t sizes[64];
39 unsigned idx;
40};
41
42static pthread_once_t lumiera_tmpbuf_tls_once = PTHREAD_ONCE_INIT;
43static pthread_key_t lumiera_tmpbuf_tls_key;
44
45void
47
48static void
50{
51 (void) buf;
53}
54
55static void
57{
60}
61
62
63void
65{
67
68 struct lumiera_tmpbuf_struct* buf = pthread_getspecific (lumiera_tmpbuf_tls_key);
69 if (buf)
70 {
71 pthread_setspecific (lumiera_tmpbuf_tls_key, NULL);
72 for (int idx = 0; idx < LUMIERA_TMPBUF_NUM; ++idx)
73 lumiera_free (buf->buffers[idx]);
74 lumiera_free (buf);
75 }
76}
77
78
79void*
81{
83
84 struct lumiera_tmpbuf_struct* buf = pthread_getspecific (lumiera_tmpbuf_tls_key);
85 if (!buf)
86 pthread_setspecific (lumiera_tmpbuf_tls_key,
87 buf = lumiera_calloc (1, sizeof (struct lumiera_tmpbuf_struct)));
88
89 buf->idx = (buf->idx + 1) & 0x3f;
90
91 if (buf->sizes[buf->idx] < size || buf->sizes[buf->idx] > 8*size)
92 {
93 lumiera_free (buf->buffers[buf->idx]);
94 buf->sizes[buf->idx] = (size+4*sizeof(long)) & ~(4*sizeof(long)-1);
95 buf->buffers[buf->idx] = lumiera_malloc (buf->sizes[buf->idx]);
96 }
97 return buf->buffers[buf->idx];
98}
99
100
101char*
102lumiera_tmpbuf_strndup (const char* src, size_t size)
103{
104 size_t len = strlen (src);
105 len = len > size ? size : len;
106
107 char* buf = lumiera_tmpbuf_provide (len + 1);
108 strncpy (buf, src, len);
109 buf[len] = '\0';
110
111 return buf;
112}
113
114
115char*
116lumiera_tmpbuf_snprintf (size_t size, const char* fmt, ...)
117{
118 va_list args;
119
120 va_start (args, fmt);
121 size_t len = vsnprintf (NULL, 0, fmt, args);
122 va_end (args);
123
124 len = len > size ? size : len;
125 char* buf = lumiera_tmpbuf_provide (len+1);
126 va_start (args, fmt);
127 vsnprintf (buf, len+1, fmt, args);
128 va_end (args);
129
130 return buf;
131}
132
133
134char*
135lumiera_tmpbuf_strcat3 (const char* str1, size_t str1_len,
136 const char* str2, size_t str2_len,
137 const char* str3, size_t str3_len)
138{
139 return lumiera_tmpbuf_snprintf (SIZE_MAX, "%.*s%s%.*s%s%.*s",
140 str1?str1_len:0, str1?str1:"", str1?".":"",
141 str2?str2_len:0, str2?str2:"",
142 str3?".":"", str3?str3_len:0, str3?str3:"");
143}
144
145
146char*
147lumiera_tmpbuf_tr (const char* in, const char* from, const char* to, const char* def)
148{
149 REQUIRE (strlen (from) == strlen (to), "from and to character set must have equal length");
150
151 char* ret = lumiera_tmpbuf_strndup (in, SIZE_MAX);
152
153 char* wpos;
154 char* rpos;
155 for (wpos = rpos = ret; *rpos; ++rpos, ++wpos)
156 {
157 char* found = strchr (from, *rpos);
158 if (found)
159 *wpos = to[found-from];
160 else if (def)
161 {
162 if (*def)
163 *wpos = *def;
164 else
165 {
166 ++rpos;
167 if (!*rpos)
168 break;
169 }
170 }
171 else
172 return NULL;
173 }
174 *wpos = '\0';
175
176 return ret;
177}
178
179
180/*
181// Local Variables:
182// mode: C
183// c-file-style: "gnu"
184// indent-tabs-mode: nil
185// End:
186*/
return NULL
Definition llist.h:586
void * lumiera_calloc(size_t n, size_t size)
Allocate cleared memory for an array.
Definition safeclib.c:130
void * lumiera_malloc(size_t size)
Allocate memory.
Definition safeclib.c:113
Portable and safe wrappers around some C-Lib functions.
static void lumiera_free(void *mem)
Free previously allocated memory.
Definition safeclib.h:73
char * lumiera_tmpbuf_tr(const char *in, const char *from, const char *to, const char *def)
Translates characters in a string, similar to the shell 'tr' utility.
Definition tmpbuf.c:147
char * lumiera_tmpbuf_strndup(const char *src, size_t size)
Duplicate string to a tmpbuf.
Definition tmpbuf.c:102
static pthread_once_t lumiera_tmpbuf_tls_once
Definition tmpbuf.c:42
char * lumiera_tmpbuf_strcat3(const char *str1, size_t str1_len, const char *str2, size_t str2_len, const char *str3, size_t str3_len)
Concat up to 3 strings in a tmpbuf.
Definition tmpbuf.c:135
size_t sizes[64]
Definition tmpbuf.c:38
void * buffers[64]
Definition tmpbuf.c:37
char * lumiera_tmpbuf_snprintf(size_t size, const char *fmt,...)
Construct a string in a tmpbuf.
Definition tmpbuf.c:116
void lumiera_tmpbuf_freeall(void)
free all buffers associated with this thread.
Definition tmpbuf.c:64
static pthread_key_t lumiera_tmpbuf_tls_key
Definition tmpbuf.c:43
void * lumiera_tmpbuf_provide(size_t size)
Query a thread local tmpbuf.
Definition tmpbuf.c:80
static void lumiera_tmpbuf_destroy(void *buf)
Definition tmpbuf.c:49
static void lumiera_tmpbuf_init(void)
Definition tmpbuf.c:56
Round robin temporary buffers.
#define LUMIERA_TMPBUF_NUM
Number of buffers in the ring This also defines how many concurent buffers can be in use in one threa...
Definition tmpbuf.h:43