]>
code.delx.au - refind/blob - filesystems/fsw_lib.c
3 * Core file system wrapper library functions.
7 * Copyright (c) 2006 Christoph Pfisterer
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the
21 * * Neither the name of Christoph Pfisterer nor the names of the
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 /* Include generated string encoding specific functions */
41 #include "fsw_strfunc.h"
45 * Allocate memory and clear it.
48 fsw_status_t
fsw_alloc_zero(int len
, void **ptr_out
)
52 status
= fsw_alloc(len
, ptr_out
);
55 fsw_memzero(*ptr_out
, len
);
60 * Duplicate a piece of data.
63 fsw_status_t
fsw_memdup(void **dest_out
, void *src
, int len
)
67 status
= fsw_alloc(len
, dest_out
);
70 fsw_memcpy(*dest_out
, src
, len
);
75 * Get the length of a string. Returns the number of characters in the string.
78 int fsw_strlen(struct fsw_string
*s
)
80 if (s
->type
== FSW_STRING_TYPE_EMPTY
)
86 * Compare two strings for equality. The two strings are compared, taking their
87 * encoding into account. If they are considered equal, boolean true is returned.
88 * Otherwise, boolean false is returned.
91 int fsw_streq(struct fsw_string
*s1
, struct fsw_string
*s2
)
93 struct fsw_string temp_s
;
95 // handle empty strings
96 if (s1
->type
== FSW_STRING_TYPE_EMPTY
) {
97 temp_s
.type
= FSW_STRING_TYPE_ISO88591
;
98 temp_s
.size
= temp_s
.len
= 0;
100 return fsw_streq(&temp_s
, s2
);
102 if (s2
->type
== FSW_STRING_TYPE_EMPTY
) {
103 temp_s
.type
= FSW_STRING_TYPE_ISO88591
;
104 temp_s
.size
= temp_s
.len
= 0;
106 return fsw_streq(s1
, &temp_s
);
109 // check length (count of chars)
110 if (s1
->len
!= s2
->len
)
112 if (s1
->len
== 0) // both strings are empty
115 if (s1
->type
== s2
->type
) {
116 // same type, do a dumb memory compare
117 if (s1
->size
!= s2
->size
)
119 return fsw_memeq(s1
->data
, s2
->data
, s1
->size
);
122 // dispatch to type-specific functions
123 #define STREQ_DISPATCH(type1, type2) \
124 if (s1->type == FSW_STRING_TYPE_##type1 && s2->type == FSW_STRING_TYPE_##type2) \
125 return fsw_streq_##type1##_##type2(s1->data, s2->data, s1->len); \
126 if (s2->type == FSW_STRING_TYPE_##type1 && s1->type == FSW_STRING_TYPE_##type2) \
127 return fsw_streq_##type1##_##type2(s2->data, s1->data, s1->len);
128 STREQ_DISPATCH(ISO88591
, UTF8
);
129 STREQ_DISPATCH(ISO88591
, UTF16
);
130 STREQ_DISPATCH(ISO88591
, UTF16_SWAPPED
);
131 STREQ_DISPATCH(UTF8
, UTF16
);
132 STREQ_DISPATCH(UTF8
, UTF16_SWAPPED
);
133 STREQ_DISPATCH(UTF16
, UTF16_SWAPPED
);
140 * Compare a string with a C string constant. This sets up a string descriptor
141 * for the string constant (second argument) and runs fsw_streq on the two
142 * strings. Currently the C string is interpreted as ISO 8859-1.
143 * Returns boolean true if the strings are considered equal, boolean false otherwise.
146 int fsw_streq_cstr(struct fsw_string
*s1
, const char *s2
)
148 struct fsw_string temp_s
;
151 for (i
= 0; s2
[i
]; i
++)
154 temp_s
.type
= FSW_STRING_TYPE_ISO88591
;
155 temp_s
.size
= temp_s
.len
= i
;
156 temp_s
.data
= (char *)s2
;
158 return fsw_streq(s1
, &temp_s
);
162 * Creates a duplicate of a string, converting it to the given encoding during the copy.
163 * If the function returns FSW_SUCCESS, the caller must free the string later with
167 fsw_status_t
fsw_strdup_coerce(struct fsw_string
*dest
, int type
, struct fsw_string
*src
)
171 if (src
->type
== FSW_STRING_TYPE_EMPTY
|| src
->len
== 0) {
173 dest
->size
= dest
->len
= 0;
178 if (src
->type
== type
) {
180 dest
->len
= src
->len
;
181 dest
->size
= src
->size
;
182 status
= fsw_alloc(dest
->size
, &dest
->data
);
186 fsw_memcpy(dest
->data
, src
->data
, dest
->size
);
190 // dispatch to type-specific functions
191 #define STRCOERCE_DISPATCH(type1, type2) \
192 if (src->type == FSW_STRING_TYPE_##type1 && type == FSW_STRING_TYPE_##type2) \
193 return fsw_strcoerce_##type1##_##type2(src->data, src->len, dest);
194 STRCOERCE_DISPATCH(UTF8
, ISO88591
);
195 STRCOERCE_DISPATCH(UTF16
, ISO88591
);
196 STRCOERCE_DISPATCH(UTF16_SWAPPED
, ISO88591
);
197 STRCOERCE_DISPATCH(ISO88591
, UTF8
);
198 STRCOERCE_DISPATCH(UTF16
, UTF8
);
199 STRCOERCE_DISPATCH(UTF16_SWAPPED
, UTF8
);
200 STRCOERCE_DISPATCH(ISO88591
, UTF16
);
201 STRCOERCE_DISPATCH(UTF8
, UTF16
);
202 STRCOERCE_DISPATCH(UTF16_SWAPPED
, UTF16
);
204 return FSW_UNSUPPORTED
;
208 * Splits a string at the first occurence of the separator character.
209 * The buffer string is searched for the separator character. If it is found, the
210 * element string descriptor is filled to point at the part of the buffer string
211 * before the separator. The buffer string itself is adjusted to point at the
212 * remaining part of the string (without the separator).
214 * If the separator is not found in the buffer string, then element is changed to
215 * point at the whole buffer string, and the buffer string itself is changed into
218 * This function only manipulates the pointers and lengths in the two string descriptors,
219 * it does not change the actual string. If the buffer string is dynamically allocated,
220 * you must make a copy of it so that you can release it later.
223 void fsw_strsplit(struct fsw_string
*element
, struct fsw_string
*buffer
, char separator
)
227 if (buffer
->type
== FSW_STRING_TYPE_EMPTY
|| buffer
->len
== 0) {
228 element
->type
= FSW_STRING_TYPE_EMPTY
;
232 maxlen
= buffer
->len
;
235 if (buffer
->type
== FSW_STRING_TYPE_ISO88591
) {
238 p
= (fsw_u8
*)element
->data
;
239 for (i
= 0; i
< maxlen
; i
++, p
++) {
240 if (*p
== separator
) {
241 buffer
->data
= p
+ 1;
242 buffer
->len
-= i
+ 1;
252 element
->size
= element
->len
;
253 buffer
->size
= buffer
->len
;
255 } else if (buffer
->type
== FSW_STRING_TYPE_UTF16
) {
258 p
= (fsw_u16
*)element
->data
;
259 for (i
= 0; i
< maxlen
; i
++, p
++) {
260 if (*p
== separator
) {
261 buffer
->data
= p
+ 1;
262 buffer
->len
-= i
+ 1;
272 element
->size
= element
->len
* sizeof(fsw_u16
);
273 buffer
->size
= buffer
->len
* sizeof(fsw_u16
);
277 buffer
->type
= FSW_STRING_TYPE_EMPTY
;
280 // TODO: support UTF8 and UTF16_SWAPPED
284 * Frees the memory used by a string returned from fsw_strdup_coerce.
287 void fsw_strfree(struct fsw_string
*s
)
289 if (s
->type
!= FSW_STRING_TYPE_EMPTY
&& s
->data
)
291 s
->type
= FSW_STRING_TYPE_EMPTY
;