562
|
1 /*
|
|
2 stringbuf: mimicking a bit of C++ to more safely handle strings
|
|
3
|
|
4 copyright 2006-8 by the mpg123 project - free software under the terms of the LGPL 2.1
|
|
5 see COPYING and AUTHORS files in distribution or http://mpg123.org
|
|
6 initially written by Thomas Orgis
|
|
7 */
|
|
8
|
|
9 #include "mpg123lib_intern.h"
|
|
10 #include "config.h"
|
|
11 #include "mpg123.h"
|
|
12 #include "compat.h"
|
|
13 #include <string.h>
|
|
14 #include "debug.h"
|
|
15
|
|
16 void attribute_align_arg mpg123_init_string(mpg123_string* sb)
|
|
17 {
|
|
18 sb->p = NULL;
|
|
19 sb->size = 0;
|
|
20 sb->fill = 0;
|
|
21 }
|
|
22
|
|
23 void attribute_align_arg mpg123_free_string(mpg123_string* sb)
|
|
24 {
|
|
25 if(sb->p != NULL) free(sb->p);
|
|
26 mpg123_init_string(sb);
|
|
27 }
|
|
28
|
|
29 int attribute_align_arg mpg123_grow_string(mpg123_string* sb, size_t new)
|
|
30 {
|
|
31 if(sb->size < new) return mpg123_resize_string(sb, new);
|
|
32 else return 1;
|
|
33 }
|
|
34
|
|
35 int attribute_align_arg mpg123_resize_string(mpg123_string* sb, size_t new)
|
|
36 {
|
|
37 debug3("resizing string pointer %p from %lu to %lu", (void*) sb->p, (unsigned long)sb->size, (unsigned long)new);
|
|
38 if(new == 0)
|
|
39 {
|
|
40 if(sb->size && sb->p != NULL) free(sb->p);
|
|
41 mpg123_init_string(sb);
|
|
42 return 1;
|
|
43 }
|
|
44 if(sb->size != new)
|
|
45 {
|
|
46 char* t;
|
|
47 debug("really!");
|
|
48 t = (char*) safe_realloc(sb->p, new*sizeof(char));
|
|
49 debug1("safe_realloc returned %p", (void*) t);
|
|
50 if(t != NULL)
|
|
51 {
|
|
52 sb->p = t;
|
|
53 sb->size = new;
|
|
54 return 1;
|
|
55 }
|
|
56 else return 0;
|
|
57 }
|
|
58 else return 1; /* success */
|
|
59 }
|
|
60
|
|
61 int attribute_align_arg mpg123_copy_string(mpg123_string* from, mpg123_string* to)
|
|
62 {
|
|
63 size_t fill;
|
|
64 char *text;
|
|
65 if(to == NULL) return -1;
|
|
66
|
|
67 debug2("called copy_string with %p -> %p", (void*)from, (void*)to);
|
|
68 if(from == NULL)
|
|
69 {
|
|
70 fill = 0;
|
|
71 text = NULL;
|
|
72 }
|
|
73 else
|
|
74 {
|
|
75 fill = from->fill;
|
|
76 text = from->p;
|
|
77 }
|
|
78
|
|
79 if(mpg123_resize_string(to, fill))
|
|
80 {
|
|
81 memcpy(to->p, text, fill);
|
|
82 to->fill = fill;
|
|
83 return 1;
|
|
84 }
|
|
85 else return 0;
|
|
86 }
|
|
87
|
|
88 int attribute_align_arg mpg123_add_string(mpg123_string* sb, const char* stuff)
|
|
89 {
|
|
90 debug1("adding %s", stuff);
|
|
91 return mpg123_add_substring(sb, stuff, 0, strlen(stuff));
|
|
92 }
|
|
93
|
|
94 int attribute_align_arg mpg123_add_substring(mpg123_string *sb, const char *stuff, size_t from, size_t count)
|
|
95 {
|
|
96 debug("adding a substring");
|
|
97 if(sb->fill) /* includes zero byte... */
|
|
98 {
|
|
99 if( (SIZE_MAX - sb->fill >= count) /* Avoid overflow. */
|
|
100 && (sb->size >= sb->fill+count || mpg123_grow_string(sb, sb->fill+count)) )
|
|
101 {
|
|
102 memcpy(sb->p+sb->fill-1, stuff+from, count);
|
|
103 sb->fill += count;
|
|
104 sb->p[sb->fill-1] = 0; /* Terminate! */
|
|
105 }
|
|
106 else return 0;
|
|
107 }
|
|
108 else
|
|
109 {
|
|
110 if( count < SIZE_MAX && mpg123_grow_string(sb, count+1) )
|
|
111 {
|
|
112 memcpy(sb->p, stuff+from, count);
|
|
113 sb->fill = count+1;
|
|
114 sb->p[sb->fill-1] = 0; /* Terminate! */
|
|
115 }
|
|
116 else return 0;
|
|
117 }
|
|
118 return 1;
|
|
119 }
|
|
120
|
|
121 int attribute_align_arg mpg123_set_substring(mpg123_string* sb, const char* stuff, size_t from, size_t count)
|
|
122 {
|
|
123 sb->fill = 0;
|
|
124 return mpg123_add_substring(sb, stuff, from, count);
|
|
125 }
|
|
126
|
|
127 int attribute_align_arg mpg123_set_string(mpg123_string* sb, const char* stuff)
|
|
128 {
|
|
129 sb->fill = 0;
|
|
130 return mpg123_add_string(sb, stuff);
|
|
131 }
|