]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - vtoycli/fat_io_lib/release/fat_string.c
1 //-----------------------------------------------------------------------------
2 //-----------------------------------------------------------------------------
3 // FAT16/32 File IO Library
6 // Copyright 2003 - 2012
8 // Email: admin@ultra-embedded.com
11 // If you would like a version with a more permissive license for use in
12 // closed source commercial applications please contact me for details.
13 //-----------------------------------------------------------------------------
15 // This file is part of FAT File IO Library.
17 // FAT File IO Library is free software; you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation; either version 2 of the License, or
20 // (at your option) any later version.
22 // FAT File IO Library is distributed in the hope that it will be useful,
23 // but WITHOUT ANY WARRANTY; without even the implied warranty of
24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 // GNU General Public License for more details.
27 // You should have received a copy of the GNU General Public License
28 // along with FAT File IO Library; if not, write to the Free Software
29 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 //-----------------------------------------------------------------------------
31 //-----------------------------------------------------------------------------
34 #include "fat_string.h"
36 //-----------------------------------------------------------------------------
37 // fatfs_total_path_levels: Take a filename and path and count the sub levels
38 // of folders. E.g. C:\folder\file.zip = 1 level
39 // Acceptable input formats are:
41 // /dev/etc/samba.conf
42 // Returns: -1 = Error, 0 or more = Ok
43 //-----------------------------------------------------------------------------
44 int fatfs_total_path_levels(char *path
)
52 // Acceptable formats:
54 // /dev/etc/samba.conf
60 else if (path
[1] == ':' || path
[2] == '\\')
68 // Count levels in path string
71 // Fast forward through actual subdir text to next slash
74 // If slash detected escape from for loop
75 if (*path
== expectedchar
) { path
++; break; }
79 // Increase number of subdirs founds
83 // Subtract the file itself
86 //-----------------------------------------------------------------------------
87 // fatfs_get_substring: Get a substring from 'path' which contains the folder
88 // (or file) at the specified level.
89 // E.g. C:\folder\file.zip : Level 0 = C:\folder, Level 1 = file.zip
90 // Returns: -1 = Error, 0 = Ok
91 //-----------------------------------------------------------------------------
92 int fatfs_get_substring(char *path
, int levelreq
, char *output
, int max_len
)
100 if (!path
|| max_len
<= 0)
103 // Acceptable formats:
104 // c:\folder\file.zip
105 // /dev/etc/samba.conf
111 else if (path
[1] == ':' || path
[2] == '\\')
119 // Get string length of path
120 pathlen
= (int)strlen (path
);
122 // Loop through the number of times as characters in 'path'
123 for (i
= 0; i
<pathlen
; i
++)
125 // If a '\' is found then increase level
126 if (*path
== expectedchar
) levels
++;
128 // If correct level and the character is not a '\' or '/' then copy text to 'output'
129 if ( (levels
== levelreq
) && (*path
!= expectedchar
) && (copypnt
< (max_len
-1)))
130 output
[copypnt
++] = *path
;
132 // Increment through path string
137 output
[copypnt
] = '\0';
139 // If a string was copied return 0 else return 1
140 if (output
[0] != '\0')
145 //-----------------------------------------------------------------------------
146 // fatfs_split_path: Full path contains the passed in string.
147 // Returned is the path string and file Name string
148 // E.g. C:\folder\file.zip -> path = C:\folder filename = file.zip
149 // E.g. C:\file.zip -> path = [blank] filename = file.zip
150 //-----------------------------------------------------------------------------
151 int fatfs_split_path(char *full_path
, char *path
, int max_path
, char *filename
, int max_filename
)
155 // Count the levels to the filepath
156 int levels
= fatfs_total_path_levels(full_path
);
160 // Get filename part of string
161 if (fatfs_get_substring(full_path
, levels
, filename
, max_filename
) != 0)
169 strindex
= (int)strlen(full_path
) - (int)strlen(filename
);
170 if (strindex
> max_path
)
173 memcpy(path
, full_path
, strindex
);
174 path
[strindex
-1] = '\0';
179 //-----------------------------------------------------------------------------
180 // FileString_StrCmpNoCase: Compare two strings case with case sensitivity
181 //-----------------------------------------------------------------------------
182 static int FileString_StrCmpNoCase(char *s1
, char *s2
, int n
)
192 // Make lower case if uppercase
193 if ((a
>='A') && (a
<='Z'))
195 if ((b
>='A') && (b
<='Z'))
204 // If run out of strings
205 if ( (*s1
== 0) || (*s2
== 0) )
213 //-----------------------------------------------------------------------------
214 // FileString_GetExtension: Get index to extension within filename
215 // Returns -1 if not found or index otherwise
216 //-----------------------------------------------------------------------------
217 static int FileString_GetExtension(char *str
)
222 // Find last '.' in string (if at all)
226 dotPos
= (int)(strSrc
-str
);
233 //-----------------------------------------------------------------------------
234 // FileString_TrimLength: Get length of string excluding trailing spaces
235 // Returns -1 if not found or index otherwise
236 //-----------------------------------------------------------------------------
237 static int FileString_TrimLength(char *str
, int strLen
)
240 char *strSrc
= str
+strLen
-1;
242 // Find last non white space
246 length
= (int)(strSrc
- str
);
256 //-----------------------------------------------------------------------------
257 // fatfs_compare_names: Compare two filenames (without copying or changing origonals)
258 // Returns 1 if match, 0 if not
259 //-----------------------------------------------------------------------------
260 int fatfs_compare_names(char* strA
, char* strB
)
264 int ext1Pos
, ext2Pos
;
265 int file1Len
, file2Len
;
267 // Get both files extension
268 ext1Pos
= FileString_GetExtension(strA
);
269 ext2Pos
= FileString_GetExtension(strB
);
271 // NOTE: Extension position can be different for matching
272 // filename if trailing space are present before it!
273 // Check that if one has an extension, so does the other
274 if ((ext1Pos
==-1) && (ext2Pos
!=-1))
276 if ((ext2Pos
==-1) && (ext1Pos
!=-1))
279 // If they both have extensions, compare them
282 // Set pointer to start of extension
283 ext1
= strA
+ext1Pos
+1;
284 ext2
= strB
+ext2Pos
+1;
286 // Verify that the file extension lengths match!
287 if (strlen(ext1
) != strlen(ext2
))
290 // If they dont match
291 if (FileString_StrCmpNoCase(ext1
, ext2
, (int)strlen(ext1
))!=0)
294 // Filelength is upto extensions
301 // Filelength is actual filelength
302 file1Len
= (int)strlen(strA
);
303 file2Len
= (int)strlen(strB
);
306 // Find length without trailing spaces (before ext)
307 file1Len
= FileString_TrimLength(strA
, file1Len
);
308 file2Len
= FileString_TrimLength(strB
, file2Len
);
310 // Check the file lengths match
311 if (file1Len
!=file2Len
)
314 // Compare main part of filenames
315 if (FileString_StrCmpNoCase(strA
, strB
, file1Len
)!=0)
320 //-----------------------------------------------------------------------------
321 // fatfs_string_ends_with_slash: Does the string end with a slash (\ or /)
322 //-----------------------------------------------------------------------------
323 int fatfs_string_ends_with_slash(char *path
)
332 if (*path
== '\\' || *path
== '/')
342 //-----------------------------------------------------------------------------
343 // fatfs_get_sfn_display_name: Get display name for SFN entry
344 //-----------------------------------------------------------------------------
345 int fatfs_get_sfn_display_name(char* out
, char* in
)
348 while (*in
&& len
<= 11)
354 // Make lower case if uppercase
355 else if ((a
>='A') && (a
<='Z'))
365 //-----------------------------------------------------------------------------
366 // fatfs_get_extension: Get extension of filename passed in 'filename'.
367 // Returned extension is always lower case.
368 // Returns: 1 if ok, 0 if not.
369 //-----------------------------------------------------------------------------
370 int fatfs_get_extension(char* filename
, char* out
, int maxlen
)
374 // Get files extension offset
375 int ext_pos
= FileString_GetExtension(filename
);
377 if (ext_pos
> 0 && out
&& maxlen
)
379 filename
+= ext_pos
+ 1;
381 while (*filename
&& len
< (maxlen
-1))
383 char a
= *filename
++;
385 // Make lowercase if uppercase
386 if ((a
>='A') && (a
<='Z'))
399 //-----------------------------------------------------------------------------
400 // fatfs_create_path_string: Append path & filename to create file path string.
401 // Returns: 1 if ok, 0 if not.
402 //-----------------------------------------------------------------------------
403 int fatfs_create_path_string(char* path
, char *filename
, char* out
, int maxlen
)
407 char seperator
= '/';
409 if (path
&& filename
&& out
&& maxlen
> 0)
411 while (*path
&& len
< (maxlen
-2))
420 // Add a seperator if trailing one not found
421 if (last
!= '\\' && last
!= '/')
424 while (*filename
&& len
< (maxlen
-1))
426 *out
++ = *filename
++;
437 //-----------------------------------------------------------------------------
439 //-----------------------------------------------------------------------------
440 #ifdef FAT_STRING_TESTBENCH
446 assert(fatfs_total_path_levels("C:\\folder\\file.zip") == 1);
447 assert(fatfs_total_path_levels("C:\\file.zip") == 0);
448 assert(fatfs_total_path_levels("C:\\folder\\folder2\\file.zip") == 2);
449 assert(fatfs_total_path_levels("C:\\") == -1);
450 assert(fatfs_total_path_levels("") == -1);
451 assert(fatfs_total_path_levels("/dev/etc/file.zip") == 2);
452 assert(fatfs_total_path_levels("/dev/file.zip") == 1);
454 assert(fatfs_get_substring("C:\\folder\\file.zip", 0, output
, sizeof(output
)) == 0);
455 assert(strcmp(output
, "folder") == 0);
457 assert(fatfs_get_substring("C:\\folder\\file.zip", 1, output
, sizeof(output
)) == 0);
458 assert(strcmp(output
, "file.zip") == 0);
460 assert(fatfs_get_substring("/dev/etc/file.zip", 0, output
, sizeof(output
)) == 0);
461 assert(strcmp(output
, "dev") == 0);
463 assert(fatfs_get_substring("/dev/etc/file.zip", 1, output
, sizeof(output
)) == 0);
464 assert(strcmp(output
, "etc") == 0);
466 assert(fatfs_get_substring("/dev/etc/file.zip", 2, output
, sizeof(output
)) == 0);
467 assert(strcmp(output
, "file.zip") == 0);
469 assert(fatfs_split_path("C:\\folder\\file.zip", output
, sizeof(output
), output2
, sizeof(output2
)) == 0);
470 assert(strcmp(output
, "C:\\folder") == 0);
471 assert(strcmp(output2
, "file.zip") == 0);
473 assert(fatfs_split_path("C:\\file.zip", output
, sizeof(output
), output2
, sizeof(output2
)) == 0);
474 assert(output
[0] == 0);
475 assert(strcmp(output2
, "file.zip") == 0);
477 assert(fatfs_split_path("/dev/etc/file.zip", output
, sizeof(output
), output2
, sizeof(output2
)) == 0);
478 assert(strcmp(output
, "/dev/etc") == 0);
479 assert(strcmp(output2
, "file.zip") == 0);
481 assert(FileString_GetExtension("C:\\file.zip") == strlen("C:\\file"));
482 assert(FileString_GetExtension("C:\\file.zip.ext") == strlen("C:\\file.zip"));
483 assert(FileString_GetExtension("C:\\file.zip.") == strlen("C:\\file.zip"));
485 assert(FileString_TrimLength("C:\\file.zip", strlen("C:\\file.zip")) == strlen("C:\\file.zip"));
486 assert(FileString_TrimLength("C:\\file.zip ", strlen("C:\\file.zip ")) == strlen("C:\\file.zip"));
487 assert(FileString_TrimLength(" ", strlen(" ")) == 0);
489 assert(fatfs_compare_names("C:\\file.ext", "C:\\file.ext") == 1);
490 assert(fatfs_compare_names("C:\\file2.ext", "C:\\file.ext") == 0);
491 assert(fatfs_compare_names("C:\\file .ext", "C:\\file.ext") == 1);
492 assert(fatfs_compare_names("C:\\file .ext", "C:\\file2.ext") == 0);
494 assert(fatfs_string_ends_with_slash("C:\\folder") == 0);
495 assert(fatfs_string_ends_with_slash("C:\\folder\\") == 1);
496 assert(fatfs_string_ends_with_slash("/path") == 0);
497 assert(fatfs_string_ends_with_slash("/path/a") == 0);
498 assert(fatfs_string_ends_with_slash("/path/") == 1);
500 assert(fatfs_get_extension("/mypath/file.wav", output
, 4) == 1);
501 assert(strcmp(output
, "wav") == 0);
502 assert(fatfs_get_extension("/mypath/file.WAV", output
, 4) == 1);
503 assert(strcmp(output
, "wav") == 0);
504 assert(fatfs_get_extension("/mypath/file.zip", output
, 4) == 1);
505 assert(strcmp(output
, "ext") != 0);
507 assert(fatfs_create_path_string("/mydir1", "myfile.txt", output
, sizeof(output
)) == 1);
508 assert(strcmp(output
, "/mydir1/myfile.txt") == 0);
509 assert(fatfs_create_path_string("/mydir2/", "myfile2.txt", output
, sizeof(output
)) == 1);
510 assert(strcmp(output
, "/mydir2/myfile2.txt") == 0);
511 assert(fatfs_create_path_string("C:\\mydir3", "myfile3.txt", output
, sizeof(output
)) == 1);
512 assert(strcmp(output
, "C:\\mydir3\\myfile3.txt") == 0);