Mercurial > hg > sv-dependency-builds
comparison src/libsndfile-1.0.25/src/strings.c @ 0:c7265573341e
Import initial set of sources
author | Chris Cannam |
---|---|
date | Mon, 18 Mar 2013 14:12:14 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c7265573341e |
---|---|
1 /* | |
2 ** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com> | |
3 ** | |
4 ** This program is free software; you can redistribute it and/or modify | |
5 ** it under the terms of the GNU Lesser General Public License as published by | |
6 ** the Free Software Foundation; either version 2.1 of the License, or | |
7 ** (at your option) any later version. | |
8 ** | |
9 ** This program is distributed in the hope that it will be useful, | |
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ** GNU Lesser General Public License for more details. | |
13 ** | |
14 ** You should have received a copy of the GNU Lesser General Public License | |
15 ** along with this program; if not, write to the Free Software | |
16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
17 */ | |
18 | |
19 #include "sfconfig.h" | |
20 | |
21 #include <stdio.h> | |
22 #include <string.h> | |
23 #include <math.h> | |
24 | |
25 #include "sndfile.h" | |
26 #include "common.h" | |
27 | |
28 #define STRINGS_DEBUG 0 | |
29 #if STRINGS_DEBUG | |
30 static void hexdump (void *data, int len) ; | |
31 #endif | |
32 | |
33 int | |
34 psf_store_string (SF_PRIVATE *psf, int str_type, const char *str) | |
35 { char new_str [128] ; | |
36 size_t len_remaining, str_len ; | |
37 int k, str_flags ; | |
38 | |
39 if (str == NULL) | |
40 return SFE_STR_BAD_STRING ; | |
41 | |
42 str_len = strlen (str) ; | |
43 | |
44 /* A few extra checks for write mode. */ | |
45 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) | |
46 { if ((psf->str_flags & SF_STR_ALLOW_START) == 0) | |
47 return SFE_STR_NO_SUPPORT ; | |
48 if (psf->have_written && (psf->str_flags & SF_STR_ALLOW_END) == 0) | |
49 return SFE_STR_NO_SUPPORT ; | |
50 /* Only allow zero length strings for software. */ | |
51 if (str_type != SF_STR_SOFTWARE && str_len == 0) | |
52 return SFE_STR_BAD_STRING ; | |
53 } ; | |
54 | |
55 /* Find the next free slot in table. */ | |
56 for (k = 0 ; k < SF_MAX_STRINGS ; k++) | |
57 { /* If we find a matching entry clear it. */ | |
58 if (psf->strings [k].type == str_type) | |
59 psf->strings [k].type = -1 ; | |
60 | |
61 if (psf->strings [k].type == 0) | |
62 break ; | |
63 } ; | |
64 | |
65 /* Determine flags */ | |
66 str_flags = SF_STR_LOCATE_START ; | |
67 if (psf->file.mode == SFM_RDWR || psf->have_written) | |
68 { if ((psf->str_flags & SF_STR_ALLOW_END) == 0) | |
69 return SFE_STR_NO_ADD_END ; | |
70 str_flags = SF_STR_LOCATE_END ; | |
71 } ; | |
72 | |
73 /* More sanity checking. */ | |
74 if (k >= SF_MAX_STRINGS) | |
75 return SFE_STR_MAX_COUNT ; | |
76 | |
77 if (k == 0 && psf->str_end != NULL) | |
78 { psf_log_printf (psf, "SFE_STR_WEIRD : k == 0 && psf->str_end != NULL\n") ; | |
79 return SFE_STR_WEIRD ; | |
80 } ; | |
81 | |
82 if (k != 0 && psf->str_end == NULL) | |
83 { psf_log_printf (psf, "SFE_STR_WEIRD : k != 0 && psf->str_end == NULL\n") ; | |
84 return SFE_STR_WEIRD ; | |
85 } ; | |
86 | |
87 /* Special case for the first string. */ | |
88 if (k == 0) | |
89 psf->str_end = psf->str_storage ; | |
90 | |
91 switch (str_type) | |
92 { case SF_STR_SOFTWARE : | |
93 /* In write mode, want to append libsndfile-version to string. */ | |
94 if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR) | |
95 { if (strstr (str, PACKAGE) == NULL) | |
96 { /* | |
97 ** If the supplied string does not already contain a | |
98 ** libsndfile-X.Y.Z component, then add it. | |
99 */ | |
100 if (strlen (str) == 0) | |
101 snprintf (new_str, sizeof (new_str), "%s-%s", PACKAGE, VERSION) ; | |
102 else | |
103 snprintf (new_str, sizeof (new_str), "%s (%s-%s)", str, PACKAGE, VERSION) ; | |
104 } | |
105 else | |
106 snprintf (new_str, sizeof (new_str), "%s", str) ; | |
107 | |
108 str = new_str ; | |
109 } ; | |
110 break ; | |
111 | |
112 case SF_STR_TITLE : | |
113 case SF_STR_COPYRIGHT : | |
114 case SF_STR_ARTIST : | |
115 case SF_STR_COMMENT : | |
116 case SF_STR_DATE : | |
117 case SF_STR_ALBUM : | |
118 case SF_STR_LICENSE : | |
119 case SF_STR_TRACKNUMBER : | |
120 case SF_STR_GENRE : | |
121 break ; | |
122 | |
123 default : | |
124 psf_log_printf (psf, "%s : SFE_STR_BAD_TYPE\n", __func__) ; | |
125 return SFE_STR_BAD_TYPE ; | |
126 } ; | |
127 | |
128 str_len = strlen (str) ; | |
129 | |
130 len_remaining = SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage) ; | |
131 | |
132 if (len_remaining < str_len + 2) | |
133 return SFE_STR_MAX_DATA ; | |
134 | |
135 psf->strings [k].type = str_type ; | |
136 psf->strings [k].str = psf->str_end ; | |
137 psf->strings [k].flags = str_flags ; | |
138 | |
139 memcpy (psf->str_end, str, str_len + 1) ; | |
140 /* Plus one to catch string terminator. */ | |
141 psf->str_end += str_len + 1 ; | |
142 | |
143 psf->str_flags |= str_flags ; | |
144 | |
145 #if STRINGS_DEBUG | |
146 psf_log_printf (psf, "str_storage : %X\n", (int) psf->str_storage) ; | |
147 psf_log_printf (psf, "str_end : %X\n", (int) psf->str_end) ; | |
148 psf_log_printf (psf, "sizeof (str_storage) : %d\n", SIGNED_SIZEOF (psf->str_storage)) ; | |
149 psf_log_printf (psf, "used : %d\n", (int ) (psf->str_end - psf->str_storage)) ; | |
150 psf_log_printf (psf, "remaining : %d\n", SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage)) ; | |
151 | |
152 hexdump (psf->str_storage, 300) ; | |
153 #endif | |
154 | |
155 return 0 ; | |
156 } /* psf_store_string */ | |
157 | |
158 int | |
159 psf_set_string (SF_PRIVATE *psf, int str_type, const char *str) | |
160 { if (psf->file.mode == SFM_READ) | |
161 return SFE_STR_NOT_WRITE ; | |
162 | |
163 return psf_store_string (psf, str_type, str) ; | |
164 } /* psf_set_string */ | |
165 | |
166 const char* | |
167 psf_get_string (SF_PRIVATE *psf, int str_type) | |
168 { int k ; | |
169 | |
170 for (k = 0 ; k < SF_MAX_STRINGS ; k++) | |
171 if (str_type == psf->strings [k].type) | |
172 return psf->strings [k].str ; | |
173 | |
174 return NULL ; | |
175 } /* psf_get_string */ | |
176 | |
177 int | |
178 psf_location_string_count (const SF_PRIVATE * psf, int location) | |
179 { int k, count = 0 ; | |
180 | |
181 for (k = 0 ; k < SF_MAX_STRINGS ; k++) | |
182 if (psf->strings [k].type > 0 && psf->strings [k].flags & location) | |
183 count ++ ; | |
184 | |
185 return count ; | |
186 } /* psf_location_string_count */ | |
187 | |
188 /*============================================================================== | |
189 */ | |
190 | |
191 #if STRINGS_DEBUG | |
192 | |
193 #include <ctype.h> | |
194 static void | |
195 hexdump (void *data, int len) | |
196 { unsigned char *ptr ; | |
197 int k ; | |
198 | |
199 ptr = data ; | |
200 | |
201 puts ("---------------------------------------------------------") ; | |
202 while (len >= 16) | |
203 { for (k = 0 ; k < 16 ; k++) | |
204 printf ("%02X ", ptr [k] & 0xFF) ; | |
205 printf (" ") ; | |
206 for (k = 0 ; k < 16 ; k++) | |
207 printf ("%c", psf_isprint (ptr [k]) ? ptr [k] : '.') ; | |
208 puts ("") ; | |
209 ptr += 16 ; | |
210 len -= 16 ; | |
211 } ; | |
212 } /* hexdump */ | |
213 | |
214 #endif |