nix startup on theme fail, fixes for font init and titler color model
[goodguy/history.git] / cinelerra-5.0 / guicast / bchash.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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, MA  02111-1307  USA
19  *
20  */
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
25
26 #include "bchash.h"
27 #include "bcsignals.h"
28 #include "filesystem.h"
29 #include "format.inc"
30 #include "stringfile.h"
31
32 BC_Hash::BC_Hash()
33 {
34         this->filename[0] = 0;
35         total = 0;
36         allocated = 0;
37         names = 0;
38         values = 0;
39 }
40
41 BC_Hash::BC_Hash(const char *filename)
42 {
43         strcpy(this->filename, filename);
44         total = 0;
45         allocated = 0;
46         names = 0;
47         values = 0;
48
49         FileSystem directory;
50
51         directory.parse_tildas(this->filename);
52         total = 0;
53 }
54
55 BC_Hash::~BC_Hash()
56 {
57         for(int i = 0; i < total; i++)
58         {
59                 delete [] names[i];
60                 delete [] values[i];
61         }
62         delete [] names;
63         delete [] values;
64 }
65
66 void BC_Hash::reallocate_table(int new_total)
67 {
68         if(allocated < new_total)
69         {
70                 int new_allocated = new_total * 2;
71                 char **new_names = new char*[new_allocated];
72                 char **new_values = new char*[new_allocated];
73
74                 for(int i = 0; i < total; i++)
75                 {
76                         new_names[i] = names[i];
77                         new_values[i] = values[i];
78                 }
79
80                 delete [] names;
81                 delete [] values;
82
83                 names = new_names;
84                 values = new_values;
85                 allocated = new_allocated;
86         }
87 }
88
89 int BC_Hash::load()
90 {
91         StringFile stringfile(filename);
92         load_stringfile(&stringfile);
93         return 0;
94 }
95
96 void BC_Hash::load_stringfile(StringFile *file)
97 {
98         char arg1[1024], arg2[1024];
99         total = 0;
100         while(file->get_pointer() < file->get_length())
101         {
102                 file->readline(arg1, arg2);
103                 reallocate_table(total + 1);
104                 names[total] = new char[strlen(arg1) + 1];
105                 values[total] = new char[strlen(arg2) + 1];
106                 strcpy(names[total], arg1);
107                 strcpy(values[total], arg2);
108                 total++;
109         }
110 }
111
112 void BC_Hash::save_stringfile(StringFile *file)
113 {
114         for(int i = 0; i < total; i++)
115         {
116                 file->writeline(names[i], values[i], 0);
117         }
118 }
119
120 int BC_Hash::save()
121 {
122         StringFile stringfile;
123         save_stringfile(&stringfile);
124         stringfile.write_to_file(filename);
125         return 0;
126 }
127
128 int BC_Hash::load_string(const char *string)
129 {
130         StringFile stringfile;
131         stringfile.read_from_string(string);
132         load_stringfile(&stringfile);
133         return 0;
134 }
135
136 int BC_Hash::save_string(char* &string)
137 {
138         StringFile stringfile;
139         save_stringfile(&stringfile);
140         string = new char[stringfile.get_length() + 1];
141         memcpy(string, stringfile.string, stringfile.get_length() + 1);
142         return 0;
143 }
144
145
146
147 int32_t BC_Hash::get(const char *name, int32_t default_)
148 {
149         for(int i = 0; i < total; i++)
150         {
151                 if(!strcmp(names[i], name))
152                 {
153                         return (int32_t)atol(values[i]);
154                 }
155         }
156         return default_;  // failed
157 }
158
159 int64_t BC_Hash::get(const char *name, int64_t default_)
160 {
161         int64_t result = default_;
162         for(int i = 0; i < total; i++)
163         {
164                 if(!strcmp(names[i], name))
165                 {
166                         sscanf(values[i], _LD, &result);
167                         return result;
168                 }
169         }
170         return result;
171 }
172
173 double BC_Hash::get(const char *name, double default_)
174 {
175         for(int i = 0; i < total; i++)
176         {
177                 if(!strcmp(names[i], name))
178                 {
179                         return atof(values[i]);
180                 }
181         }
182         return default_;  // failed
183 }
184
185 float BC_Hash::get(const char *name, float default_)
186 {
187         for(int i = 0; i < total; i++)
188         {
189                 if(!strcmp(names[i], name))
190                 {
191                         return atof(values[i]);
192                 }
193         }
194         return default_;  // failed
195 }
196
197 char* BC_Hash::get(const char *name, char *default_)
198 {
199         for(int i = 0; i < total; i++)
200         {
201                 if(!strcmp(names[i], name))
202                 {
203                         strcpy(default_, values[i]);
204                         return values[i];
205                 }
206         }
207         return default_;  // failed
208 }
209
210 int BC_Hash::update(const char *name, double value) // update a value if it exists
211 {
212         char string[BCSTRLEN];
213         sprintf(string, "%.16e", value);
214         return update(name, string);
215 }
216
217 int BC_Hash::update(const char *name, float value) // update a value if it exists
218 {
219         char string[BCSTRLEN];
220         sprintf(string, "%.6e", value);
221         return update(name, string);
222 }
223
224 int BC_Hash::update(const char *name, int32_t value) // update a value if it exists
225 {
226         char string[BCSTRLEN];
227         sprintf(string, "%d", value);
228         return update(name, string);
229 }
230
231 int BC_Hash::update(const char *name, int64_t value) // update a value if it exists
232 {
233         char string[BCSTRLEN];
234         sprintf(string, _LD, value);
235         return update(name, string);
236 }
237
238 int BC_Hash::update(const char *name, const char *value)
239 {
240         for(int i = 0; i < total; i++)
241         {
242                 if(!strcmp(names[i], name))
243                 {
244                         delete [] values[i];
245                         values[i] = new char[strlen(value) + 1];
246                         strcpy(values[i], value);
247                         return 0;
248                 }
249         }
250
251 // didn't find so create new entry
252         reallocate_table(total + 1);
253         names[total] = new char[strlen(name) + 1];
254         strcpy(names[total], name);
255         values[total] = new char[strlen(value) + 1];
256         strcpy(values[total], value);
257         total++;
258         return 1;
259 }
260
261 #define varFn(rtyp, fn, typ) \
262 rtyp BC_Hash::fn##f(typ value, const char *fmt, ...) { \
263   char string[BCTEXTLEN];  va_list ap; va_start(ap, fmt); \
264   vsnprintf(string, BCTEXTLEN, fmt, ap); \
265   va_end(ap);  return fn(string, value); \
266 }
267
268 varFn(int,update,double)        varFn(double,get,double)
269 varFn(int,update,float)         varFn(float,get,float)
270 varFn(int,update,int32_t)       varFn(int32_t,get,int32_t)
271 varFn(int,update,int64_t)       varFn(int64_t,get,int64_t)
272 varFn(int,update,const char *)  varFn(char *,get,char *)
273
274
275 void BC_Hash::copy_from(BC_Hash *src)
276 {
277 // Can't delete because this is used by file decoders after plugins
278 // request data.
279 //      for(int i = 0; i < total; i++)
280 //      {
281 //              delete [] names[i];
282 //              delete [] values[i];
283 //      }
284 //      delete [] names;
285 //      delete [] values;
286 //
287 //      allocated = 0;
288 //      names = 0;
289 //      values = 0;
290 //      total = 0;
291
292 SET_TRACE
293         reallocate_table(src->total);
294 //      total = src->total;
295 SET_TRACE
296         for(int i = 0; i < src->total; i++)
297         {
298                 update(src->names[i], src->values[i]);
299 //              names[i] = new char[strlen(src->names[i]) + 1];
300 //              values[i] = new char[strlen(src->values[i]) + 1];
301 //              strcpy(names[i], src->names[i]);
302 //              strcpy(values[i], src->values[i]);
303         }
304 SET_TRACE
305 }
306
307 int BC_Hash::equivalent(BC_Hash *src)
308 {
309         for(int i = 0; i < total && i < src->total; i++)
310         {
311                 if(strcmp(names[i], src->names[i]) ||
312                         strcmp(values[i], src->values[i])) return 0;
313         }
314         return 1;
315 }
316
317 int BC_Hash::size()
318 {
319         return total;
320 }
321
322 char* BC_Hash::get_key(int number)
323 {
324         return names[number];
325 }
326
327 char* BC_Hash::get_value(int number)
328 {
329         return values[number];
330 }
331
332
333 void BC_Hash::dump()
334 {
335         printf("BC_Hash::dump\n");
336         for(int i = 0; i < total; i++)
337                 printf("        key=%s value=%s\n", names[i], values[i]);
338 }