- Create another branch for networking fixes
[reactos.git] / lib / 3rdparty / fullfat / ff_string.c
1 /*****************************************************************************
2 * FullFAT - High Performance, Thread-Safe Embedded FAT File-System *
3 * Copyright (C) 2009 James Walmsley (james@worm.me.uk) *
4 * *
5 * This program is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 * *
18 * IMPORTANT NOTICE: *
19 * ================= *
20 * Alternative Licensing is available directly from the Copyright holder, *
21 * (James Walmsley). For more information consult LICENSING.TXT to obtain *
22 * a Commercial license. *
23 * *
24 * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. *
25 * *
26 * Removing the above notice is illegal and will invalidate this license. *
27 *****************************************************************************
28 * See http://worm.me.uk/fullfat for more information. *
29 * Or http://fullfat.googlecode.com/ for latest releases and the wiki. *
30 *****************************************************************************/
31
32 /**
33 * @file ff_string.c
34 * @author James Walmsley
35 * @ingroup STRING
36 *
37 * @defgroup STRING FullFAT String Library
38 * @brief Portable String Library for FullFAT
39 *
40 *
41 **/
42
43 #include <stdlib.h>
44 #include <string.h>
45 #include "ff_string.h"
46
47 /*
48 * These will eventually be moved into a platform independent string
49 * library. Which will be optional. (To allow the use of system specific versions).
50 */
51
52 /**
53 * @private
54 * @brief Converts an ASCII string to lowercase.
55 **/
56 void FF_tolower(FF_T_INT8 *string, FF_T_UINT32 strLen) {
57 FF_T_UINT32 i;
58 for(i = 0; i < strLen; i++) {
59 if(string[i] >= 'A' && string[i] <= 'Z')
60 string[i] += 32;
61 if(string[i] == '\0')
62 break;
63 }
64 }
65
66 /**
67 * @private
68 * @brief Converts an ASCII string to uppercase.
69 **/
70 void FF_toupper(FF_T_INT8 *string, FF_T_UINT32 strLen) {
71 FF_T_UINT32 i;
72 for(i = 0; i < strLen; i++) {
73 if(string[i] >= 'a' && string[i] <= 'z')
74 string[i] -= 32;
75 if(string[i] == '\0')
76 break;
77 }
78 }
79
80
81 /**
82 * @private
83 * @brief Compares 2 strings for the specified length, and returns FF_TRUE is they are identical
84 * otherwise FF_FALSE is returned.
85 *
86 **/
87 FF_T_BOOL FF_strmatch(const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16 len) {
88 register FF_T_UINT16 i;
89 register FF_T_INT8 char1, char2;
90
91 if(!len) {
92 if(strlen(str1) != strlen(str2)) {
93 return FF_FALSE;
94 }
95 len = (FF_T_UINT16) strlen(str1);
96 }
97
98 for(i = 0; i < len; i++) {
99 char1 = str1[i];
100 char2 = str2[i];
101 if(char1 >= 'A' && char1 <= 'Z') {
102 char1 += 32;
103 }
104 if(char2 >= 'A' && char2 <= 'Z') {
105 char2 += 32;
106 }
107
108 if(char1 != char2) {
109 return FF_FALSE;
110 }
111 }
112
113 return FF_TRUE;
114 }
115
116 /**
117 * @private
118 * @brief A re-entrant Strtok function. No documentation is provided :P
119 * Use at your own risk. (This is for FullFAT's use only).
120 **/
121 FF_T_INT8 *FF_strtok(const FF_T_INT8 *string, FF_T_INT8 *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length) {
122 FF_T_UINT16 strLen = Length;
123 FF_T_UINT16 i,y, tokenStart, tokenEnd = 0;
124
125 i = 0;
126 y = 0;
127
128 if(string[i] == '\\' || string[i] == '/') {
129 i++;
130 }
131
132 tokenStart = i;
133
134 while(i < strLen) {
135 if(string[i] == '\\' || string[i] == '/') {
136 y++;
137 if(y == *tokenNumber) {
138 tokenStart = (FF_T_UINT16)(i + 1);
139 }
140 if(y == (*tokenNumber + 1)) {
141 tokenEnd = i;
142 break;
143 }
144 }
145 i++;
146 }
147
148 if(!tokenEnd) {
149 if(*last == FF_TRUE) {
150 return NULL;
151 } else {
152 *last = FF_TRUE;
153 }
154 tokenEnd = i;
155 }
156
157 memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart));
158 token[tokenEnd - tokenStart] = '\0';
159 *tokenNumber += 1;
160
161 return token;
162 }
163
164
165 FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString) {
166 /* Check to see if the string contains the wild card */
167 if (!memchr(pszWildCard, '*', strlen(pszWildCard)))
168 {
169 /* if it does not then do a straight string compare */
170 if (strcmp(pszWildCard, pszString))
171 {
172 return FF_FALSE;
173 }
174 }
175 else
176 {
177 while ((*pszWildCard)
178 && (*pszString))
179 {
180 /* Test for the wild card */
181 if (*pszWildCard == '*')
182 {
183 /* Eat more than one */
184 while (*pszWildCard == '*')
185 {
186 pszWildCard++;
187 }
188 /* If there are more chars in the string */
189 if (*pszWildCard)
190 {
191 /* Search for the next char */
192 pszString = memchr(pszString, (int)*pszWildCard, strlen(pszString));
193 /* if it does not exist then the strings don't match */
194 if (!pszString)
195 {
196 return FF_FALSE;
197 }
198
199 }
200 else
201 {
202 if (*pszWildCard)
203 {
204 /* continue */
205 break;
206 }
207 else
208 {
209 return FF_TRUE;
210 }
211 }
212 }
213 else
214 {
215 /* Fail if they don't match */
216 if (*pszWildCard != *pszString)
217 {
218 return FF_FALSE;
219 }
220 }
221 /* Bump both pointers */
222 pszWildCard++;
223 pszString++;
224 }
225 /* fail if different lengths */
226 if (*pszWildCard != *pszString)
227 {
228 return FF_FALSE;
229 }
230 }
231
232 return FF_TRUE;
233 }
234