1 /***************************************************************************
2 types.i - Libini supported data types
3 Use readString for others
4
5 -------------------
6 begin : Fri Apr 21 2000
7 copyright : (C) 2000 by Simon White
8 email : s_a_white@email.com
9 ***************************************************************************/
10
11 /***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19
20 #include <ctype.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include "ini.h"
25
26
27 /********************************************************************************************************************
28 * Function : __ini_read
29 * Parameters : ini - pointer to ini file database, size - key length returned here
30 * Returns : -1 for Error and 0 on success.
31 * Globals Used :
32 * Globals Modified :
33 * Description : Common read functionality
34 ********************************************************************************************************************
35 * Rev | Date | By | Comment
36 * ----------------------------------------------------------------------------------------------------------------
37 ********************************************************************************************************************/
__ini_read(ini_t * ini,size_t * size)38 static int __ini_read (ini_t *ini, size_t *size)
39 {
40 struct key_tag *_key;
41
42 if (!ini->selected)
43 return -1;
44 // Locate and read keys value
45 _key = ini->selected->selected;
46 if (!_key)
47 return -1;
48
49 if (_key->length)
50 { // Locate and read back keys data
51 fseek (ini->ftmp, _key->pos, SEEK_SET);
52 }
53 else if (_key == &ini->tmpKey)
54 return -1; // Can't read tmpKey
55 *size = _key->length;
56 return 0;
57 }
58
59
60 #ifdef INI_ADD_LIST_SUPPORT
61 /********************************************************************************************************************
62 * Function : __ini_readList
63 * Parameters : ini - pointer to ini file database.
64 * Returns : Pointer to buffer holding data.
65 * Globals Used :
66 * Globals Modified :
67 * Description : Common read functionality from a list
68 ********************************************************************************************************************
69 * Rev | Date | By | Comment
70 * ----------------------------------------------------------------------------------------------------------------
71 ********************************************************************************************************************/
__ini_readList(ini_t * ini)72 static char *__ini_readList (ini_t *ini)
73 {
74 if (!ini->selected)
75 return NULL;
76 // Locate and read keys value
77 if (!ini->selected->selected)
78 return NULL;
79 return __ini_listRead (ini);
80 }
81 #endif // INI_ADD_LIST_SUPPORT
82
83
84 /********************************************************************************************************************
85 * Function : __ini_write
86 * Parameters : ini - pointer to ini file database. heading - heading name. key - key name.
87 * Returns : Pointer to new key.
88 * Globals Used :
89 * Globals Modified :
90 * Description : Make calls to add a new key and appends a description of changes in the backup file
91 ********************************************************************************************************************
92 * Rev | Date | By | Comment
93 * ----------------------------------------------------------------------------------------------------------------
94 ********************************************************************************************************************/
__ini_write(ini_t * ini)95 static struct key_tag *__ini_write (ini_t *ini)
96 {
97 struct section_tag *section;
98 struct key_tag *key;
99
100 // Is file read only?
101 if (ini->mode == INI_READ)
102 return NULL;
103
104 // Check to make sure a section/key has
105 // been asked for by the user
106 section = ini->selected;
107 if (!section)
108 return NULL;
109 key = section->selected;
110 if (!key)
111 return NULL;
112
113 // Add or replace key
114 if (!__ini_addHeading (ini, section->heading))
115 return NULL;
116 return __ini_addKey (ini, key->key);
117 }
118
119
120 /********************************************************************************************************************
121 * Function : ini_readString
122 * Parameters : ini - pointer to ini file database.
123 * : value - keys data
124 * Returns : -1 for error or the number of chars read.
125 * Globals Used :
126 * Globals Modified :
127 * Description : Reads data part from a key and returns it as a string
128 ********************************************************************************************************************
129 * Rev | Date | By | Comment
130 * ----------------------------------------------------------------------------------------------------------------
131 ********************************************************************************************************************/
ini_readString(ini_fd_t fd,char * str,size_t size)132 int INI_LINKAGE ini_readString (ini_fd_t fd, char *str, size_t size)
133 {
134 ini_t *ini = (ini_t *) fd;
135
136 // Check size and reserve space for NULL
137 if (size-- <= 0)
138 return -1;
139
140 #ifdef INI_ADD_LIST_SUPPORT
141 if (ini->listDelims)
142 {
143 char *data = __ini_readList (ini);
144 if (!data)
145 return -1;
146 strncpy (str, data, size);
147 }
148 else
149 #endif // INI_ADD_LIST_SUPPORT
150 { // Locate and read back keys data (Index ignored)
151 // Check to make sure size is correct
152 size_t length;
153 if (__ini_read (ini, &length) < 0)
154 return -1;
155 if (size > length)
156 size = length;
157 size = fread (str, sizeof(char), size, ini->ftmp);
158 }
159
160 str[size] = '\0';
161 __ini_strtrim (str);
162 return (int) size;
163 }
164
165
166 /********************************************************************************************************************
167 * Function : ini_writeString
168 * Parameters : ini - pointer to ini file database.
169 * : value - keys data
170 * Returns : -1 for Error and 0 on success
171 * Globals Used :
172 * Globals Modified :
173 * Description : Writes data part to a key.
174 * : Conforms to Microsoft API call. E.g. use NULLS to remove headings/keys
175 * : Headings and keys will be created as necessary
176 ********************************************************************************************************************
177 * Rev | Date | By | Comment
178 * ----------------------------------------------------------------------------------------------------------------
179 ********************************************************************************************************************/
ini_writeString(ini_fd_t fd,const char * str)180 int INI_LINKAGE ini_writeString (ini_fd_t fd, const char *str)
181 {
182 ini_t *ini = (ini_t *) fd;
183 struct key_tag *_key;
184
185 _key = __ini_write (ini);
186 if (!_key)
187 return -1;
188
189 // Write data to bottom of backup file
190 _key->length = strlen (str);
191 fprintf (ini->ftmp, "%s\n", str);
192 return 0;
193 }
194
195
196 /********************************************************************************************************************
197 * Function : ini_readInt
198 * Parameters : ini - pointer to ini file database.
199 * : value - keys data
200 * Returns : -1 for error or the number of values read.
201 * Globals Used :
202 * Globals Modified :
203 * Description : Reads data part from a key and returns it as a int
204 ********************************************************************************************************************
205 * Rev | Date | By | Comment
206 * ----------------------------------------------------------------------------------------------------------------
207 ********************************************************************************************************************/
ini_readInt(ini_fd_t fd,int * value)208 int INI_LINKAGE ini_readInt (ini_fd_t fd, int *value)
209 {
210 ini_t *ini = (ini_t *) fd;
211
212 #ifdef INI_ADD_LIST_SUPPORT
213 if (ini->listDelims)
214 {
215 char *data = __ini_readList (ini);
216 if (!data)
217 return -1;
218 sscanf (data, "%d", value);
219 }
220 else
221 #endif // INI_ADD_LIST_SUPPORT
222 {
223 size_t length;
224 if (__ini_read (ini, &length) < 0)
225 return -1;
226 if (length > 0)
227 fscanf (ini->ftmp, "%d", value);
228 }
229 return 0;
230 }
231
232
233 #ifdef INI_ADD_EXTRAS
234
235 /********************************************************************************************************************
236 * Function : ini_readLong
237 * Parameters : ini - pointer to ini file database.
238 * : value - keys data
239 * Returns : -1 for error or the number of values read.
240 * Globals Used :
241 * Globals Modified :
242 * Description : Reads data part from a key and returns it as a long
243 ********************************************************************************************************************
244 * Rev | Date | By | Comment
245 * ----------------------------------------------------------------------------------------------------------------
246 ********************************************************************************************************************/
ini_readLong(ini_fd_t fd,long * value)247 int INI_LINKAGE ini_readLong (ini_fd_t fd, long *value)
248 {
249 ini_t *ini = (ini_t *) fd;
250
251 #ifdef INI_ADD_LIST_SUPPORT
252 if (ini->listDelims)
253 {
254 char *data = __ini_readList (ini);
255 if (!data)
256 return -1;
257 sscanf (data, "%ld", value);
258 }
259 else
260 #endif // INI_ADD_LIST_SUPPORT
261 {
262 size_t length;
263 if (__ini_read (ini, &length) < 0)
264 return -1;
265 if (length > 0)
266 fscanf (ini->ftmp, "%ld", value);
267 }
268 return 0;
269 }
270
271
272 /********************************************************************************************************************
273 * Function : ini_readDouble
274 * Parameters : ini - pointer to ini file database.
275 * : value - keys data
276 * Returns : -1 for error or the number of values read.
277 * Globals Used :
278 * Globals Modified :
279 * Description : Reads data part from a key and returns it as a double (real)
280 ********************************************************************************************************************
281 * Rev | Date | By | Comment
282 * ----------------------------------------------------------------------------------------------------------------
283 ********************************************************************************************************************/
ini_readDouble(ini_fd_t fd,double * value)284 int INI_LINKAGE ini_readDouble (ini_fd_t fd, double *value)
285 {
286 ini_t *ini = (ini_t *) fd;
287
288 #ifdef INI_ADD_LIST_SUPPORT
289 if (ini->listDelims)
290 {
291 char *data = __ini_readList (ini);
292 if (!data)
293 return -1;
294 sscanf (data, "%lf", value);
295 }
296 else
297 #endif // INI_ADD_LIST_SUPPORT
298 {
299 size_t length;
300 if (__ini_read (ini, &length) < 0)
301 return -1;
302 if (length > 0)
303 fscanf (ini->ftmp, "%lf", value);
304 }
305 return 0;
306 }
307
308
309 /********************************************************************************************************************
310 * Function : ini_readBool
311 * Parameters : ini - pointer to ini file database.
312 * : value - keys data
313 * Returns : -1 for error or the number of values read.
314 * Globals Used :
315 * Globals Modified :
316 * Description : Reads data part from a key and returns it as a int. Supported bool strings are 0, 1, true
317 * : false.
318 ********************************************************************************************************************
319 * Rev | Date | By | Comment
320 * ----------------------------------------------------------------------------------------------------------------
321 ********************************************************************************************************************/
ini_readBool(ini_fd_t fd,int * value)322 int INI_LINKAGE ini_readBool (ini_fd_t fd, int *value)
323 {
324 ini_t *ini = (ini_t *) fd;
325 char buffer[6] = "";
326
327 #ifdef INI_ADD_LIST_SUPPORT
328 if (ini->listDelims)
329 {
330 char *data = __ini_readList (ini);
331 if (!data)
332 return -1;
333 sscanf (data, "%5s", buffer);
334 }
335 else
336 #endif // INI_ADD_LIST_SUPPORT
337 {
338 size_t length;
339 if (__ini_read (ini, &length) < 0)
340 return -1;
341 if (length > 0)
342 fscanf (ini->ftmp, "%5s", buffer);
343 }
344
345 { // Convert string to lower case
346 char *p = buffer;
347 while (*p != '\0')
348 {
349 *p = (char) tolower (*p);
350 p++;
351 }
352 }
353
354 // Decode supported bool types
355 switch (*buffer)
356 {
357 case '0':
358 case '1':
359 if (buffer[1] != '\0')
360 return -1;
361 *value = *buffer - '0';
362 break;
363 case 't':
364 if (strcmp (buffer, "true"))
365 return -1;
366 *value = 1;
367 break;
368 case 'f':
369 if (strcmp (buffer, "false"))
370 return -1;
371 *value = 0;
372 break;
373 default:
374 // No match
375 return -1;
376 }
377 return 0;
378 }
379
380
381 /********************************************************************************************************************
382 * Function : ini_writeInt
383 * Parameters : ini - pointer to ini file database.
384 * : value - keys data
385 * Returns : -1 for Error and 0 on success
386 * Globals Used :
387 * Globals Modified :
388 * Description : Writes data part to a key.
389 * : Headings and keys will be created as necessary
390 ********************************************************************************************************************
391 * Rev | Date | By | Comment
392 * ----------------------------------------------------------------------------------------------------------------
393 ********************************************************************************************************************/
ini_writeInt(ini_fd_t fd,int value)394 int INI_LINKAGE ini_writeInt (ini_fd_t fd, int value)
395 {
396 ini_t *ini = (ini_t *) fd;
397 struct key_tag *_key;
398 long pos;
399
400 _key = __ini_write (ini);
401 if (!_key)
402 return -1;
403
404 // Write data to bottom of backup file
405 fprintf (ini->ftmp, "%d", value);
406 pos = ftell (ini->ftmp);
407 _key->length = (size_t) (pos - _key->pos);
408 fprintf (ini->ftmp, "\n");
409 return 0;
410 }
411
412
413 /********************************************************************************************************************
414 * Function : ini_writeLong
415 * Parameters : ini - pointer to ini file database.
416 * : value - keys data
417 * Returns : -1 for Error and 0 on success
418 * Globals Used :
419 * Globals Modified :
420 * Description : Writes data part to a key.
421 * : Headings and keys will be created as necessary
422 ********************************************************************************************************************
423 * Rev | Date | By | Comment
424 * ----------------------------------------------------------------------------------------------------------------
425 ********************************************************************************************************************/
ini_writeLong(ini_fd_t fd,long value)426 int INI_LINKAGE ini_writeLong (ini_fd_t fd, long value)
427 {
428 ini_t *ini = (ini_t *) fd;
429 struct key_tag *_key;
430 long pos;
431
432 _key = __ini_write (ini);
433 if (!_key)
434 return -1;
435
436 // Write data to bottom of backup file
437 fprintf (ini->ftmp, "%ld", value);
438 pos = ftell (ini->ftmp);
439 _key->length = (size_t) (pos - _key->pos);
440 fprintf (ini->ftmp, "\n");
441 return 0;
442 }
443
444
445 /********************************************************************************************************************
446 * Function : ini_writeDouble
447 * Parameters : ini - pointer to ini file database.
448 * : value - keys data
449 * Returns : -1 for Error and 0 on success
450 * Globals Used :
451 * Globals Modified :
452 * Description : Writes data part to a key.
453 * : Headings and keys will be created as necessary
454 ********************************************************************************************************************
455 * Rev | Date | By | Comment
456 * ----------------------------------------------------------------------------------------------------------------
457 ********************************************************************************************************************/
ini_writeDouble(ini_fd_t fd,double value)458 int INI_LINKAGE ini_writeDouble (ini_fd_t fd, double value)
459 {
460 ini_t *ini = (ini_t *) fd;
461 struct key_tag *_key;
462 long pos;
463
464 _key = __ini_write (ini);
465 if (!_key)
466 return -1;
467
468 // Write data to bottom of backup file
469 fprintf (ini->ftmp, "%f", value);
470 pos = ftell (ini->ftmp);
471 _key->length = (size_t) (pos - _key->pos);
472 fprintf (ini->ftmp, "\n");
473 return 0;
474 }
475
476
477 /********************************************************************************************************************
478 * Function : ini_writeBool
479 * Parameters : ini - pointer to ini file database.
480 * : value - keys data
481 * Returns : -1 for Error and 0 on success
482 * Globals Used :
483 * Globals Modified :
484 * Description : Writes data part to a key.
485 * : Headings and keys will be created as necessary
486 ********************************************************************************************************************
487 * Rev | Date | By | Comment
488 * ----------------------------------------------------------------------------------------------------------------
489 ********************************************************************************************************************/
ini_writeBool(ini_fd_t fd,int value)490 int INI_LINKAGE ini_writeBool (ini_fd_t fd, int value)
491 {
492 ini_t *ini = (ini_t *) fd;
493 struct key_tag *_key;
494 long pos;
495
496 // Check if value is legal
497 if ((value < 0) || (value > 1))
498 return -1;
499
500 _key = __ini_write (ini);
501 if (!_key)
502 return -1;
503
504 // Write data to bottom of backup file
505 if (value)
506 fprintf (ini->ftmp, "true");
507 else
508 fprintf (ini->ftmp, "false");
509 pos = ftell (ini->ftmp);
510 _key->length = (size_t) (pos - _key->pos);
511 fprintf (ini->ftmp, "\n");
512 return 0;
513 }
514
515 #endif // INI_ADD_EXTRAS
516