4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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
27 #include "bcsignals.h"
28 #include "filesystem.h"
30 #include "stringfile.h"
34 this->filename[0] = 0;
41 BC_Hash::BC_Hash(const char *filename)
43 strcpy(this->filename, filename);
51 directory.parse_tildas(this->filename);
57 for(int i = 0; i < total; i++)
66 void BC_Hash::reallocate_table(int new_total)
68 if(allocated < new_total)
70 int new_allocated = new_total * 2;
71 char **new_names = new char*[new_allocated];
72 char **new_values = new char*[new_allocated];
74 for(int i = 0; i < total; i++)
76 new_names[i] = names[i];
77 new_values[i] = values[i];
85 allocated = new_allocated;
91 StringFile stringfile(filename);
92 load_stringfile(&stringfile);
96 void BC_Hash::load_stringfile(StringFile *file)
98 char arg1[1024], arg2[1024];
100 while(file->get_pointer() < file->get_length())
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);
112 void BC_Hash::save_stringfile(StringFile *file)
114 for(int i = 0; i < total; i++)
116 file->writeline(names[i], values[i], 0);
122 StringFile stringfile;
123 save_stringfile(&stringfile);
124 stringfile.write_to_file(filename);
128 int BC_Hash::load_string(const char *string)
130 StringFile stringfile;
131 stringfile.read_from_string(string);
132 load_stringfile(&stringfile);
136 int BC_Hash::save_string(char* &string)
138 StringFile stringfile;
139 save_stringfile(&stringfile);
140 string = new char[stringfile.get_length() + 1];
141 memcpy(string, stringfile.string, stringfile.get_length() + 1);
147 int32_t BC_Hash::get(const char *name, int32_t default_)
149 for(int i = 0; i < total; i++)
151 if(!strcmp(names[i], name))
153 return (int32_t)atol(values[i]);
156 return default_; // failed
159 int64_t BC_Hash::get(const char *name, int64_t default_)
161 int64_t result = default_;
162 for(int i = 0; i < total; i++)
164 if(!strcmp(names[i], name))
166 sscanf(values[i], _LD, &result);
173 double BC_Hash::get(const char *name, double default_)
175 for(int i = 0; i < total; i++)
177 if(!strcmp(names[i], name))
179 return atof(values[i]);
182 return default_; // failed
185 float BC_Hash::get(const char *name, float default_)
187 for(int i = 0; i < total; i++)
189 if(!strcmp(names[i], name))
191 return atof(values[i]);
194 return default_; // failed
197 char* BC_Hash::get(const char *name, char *default_)
199 for(int i = 0; i < total; i++)
201 if(!strcmp(names[i], name))
203 strcpy(default_, values[i]);
207 return default_; // failed
210 int BC_Hash::update(const char *name, double value) // update a value if it exists
212 char string[BCSTRLEN];
213 sprintf(string, "%.16e", value);
214 return update(name, string);
217 int BC_Hash::update(const char *name, float value) // update a value if it exists
219 char string[BCSTRLEN];
220 sprintf(string, "%.6e", value);
221 return update(name, string);
224 int BC_Hash::update(const char *name, int32_t value) // update a value if it exists
226 char string[BCSTRLEN];
227 sprintf(string, "%d", value);
228 return update(name, string);
231 int BC_Hash::update(const char *name, int64_t value) // update a value if it exists
233 char string[BCSTRLEN];
234 sprintf(string, _LD, value);
235 return update(name, string);
238 int BC_Hash::update(const char *name, const char *value)
240 for(int i = 0; i < total; i++)
242 if(!strcmp(names[i], name))
245 values[i] = new char[strlen(value) + 1];
246 strcpy(values[i], value);
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);
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); \
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 *)
275 void BC_Hash::copy_from(BC_Hash *src)
277 // Can't delete because this is used by file decoders after plugins
279 // for(int i = 0; i < total; i++)
281 // delete [] names[i];
282 // delete [] values[i];
293 reallocate_table(src->total);
294 // total = src->total;
296 for(int i = 0; i < src->total; i++)
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]);
307 int BC_Hash::equivalent(BC_Hash *src)
309 for(int i = 0; i < total && i < src->total; i++)
311 if(strcmp(names[i], src->names[i]) ||
312 strcmp(values[i], src->values[i])) return 0;
322 char* BC_Hash::get_key(int number)
324 return names[number];
327 char* BC_Hash::get_value(int number)
329 return values[number];
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]);