+++ /dev/null
-/*****************************************************************************
- * FullFAT - High Performance, Thread-Safe Embedded FAT File-System *
- * Copyright (C) 2009 James Walmsley (james@worm.me.uk) *
- * *
- * This program is free software: you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation, either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- * *
- * IMPORTANT NOTICE: *
- * ================= *
- * Alternative Licensing is available directly from the Copyright holder, *
- * (James Walmsley). For more information consult LICENSING.TXT to obtain *
- * a Commercial license. *
- * *
- * See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. *
- * *
- * Removing the above notice is illegal and will invalidate this license. *
- *****************************************************************************
- * See http://worm.me.uk/fullfat for more information. *
- * Or http://fullfat.googlecode.com/ for latest releases and the wiki. *
- *****************************************************************************/
-
-/**
- * @file ff_string.c
- * @author James Walmsley
- * @ingroup STRING
- *
- * @defgroup STRING FullFAT String Library
- * @brief Portable String Library for FullFAT
- *
- *
- **/
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include "ff_string.h"
-#include "ff_error.h"
-
-#ifdef FF_UNICODE_SUPPORT
-#include <wchar.h>
-#include <wctype.h>
-#endif
-
-/*
- * These will eventually be moved into a platform independent string
- * library. Which will be optional. (To allow the use of system specific versions).
- */
-
-#ifdef FF_UNICODE_SUPPORT
-
-void FF_cstrntowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource, FF_T_UINT32 len) {
- while(*szpSource && len--) {
- *wcsDest++ = *szpSource++;
- }
- *wcsDest = '\0';
-}
-
-void FF_cstrtowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource) {
- while(*szpSource) {
- *wcsDest++ = (FF_T_WCHAR) *szpSource++;
- }
- *wcsDest = '\0';
-}
-
-void FF_wcstocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource) {
- while(*wcsSource) {
- *szpDest++ = (FF_T_INT8) *wcsSource++;
- }
- *szpDest = '\0';
-}
-
-void FF_wcsntocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource, FF_T_UINT32 len) {
- while(*wcsSource && len--) {
- *szpDest++ = (FF_T_INT8) *wcsSource++;
- }
- *szpDest = '\0';
-}
-
-#endif
-
-/**
- * @private
- * @brief Converts an ASCII string to lowercase.
- **/
-#ifndef FF_UNICODE_SUPPORT
-/**
- * @private
- * @brief Converts an ASCII string to uppercase.
- **/
-void FF_toupper(FF_T_INT8 *string, FF_T_UINT32 strLen) {
- FF_T_UINT32 i;
- for(i = 0; i < strLen; i++) {
- if(string[i] >= 'a' && string[i] <= 'z')
- string[i] -= 32;
- if(string[i] == '\0')
- break;
- }
-}
-void FF_tolower(FF_T_INT8 *string, FF_T_UINT32 strLen) {
- FF_T_UINT32 i;
- for(i = 0; i < strLen; i++) {
- if(string[i] >= 'A' && string[i] <= 'Z')
- string[i] += 32;
- if(string[i] == '\0')
- break;
- }
-}
-
-#else
-void FF_toupper(FF_T_WCHAR *string, FF_T_UINT32 strLen) {
- FF_T_UINT32 i;
- for(i = 0; i < strLen; i++) {
- string[i] = towupper(string[i]);
- }
-}
-void FF_tolower(FF_T_WCHAR *string, FF_T_UINT32 strLen) {
- FF_T_UINT32 i;
- for(i = 0; i < strLen; i++) {
- string[i] = towlower(string[i]);
- }
-}
-#endif
-
-
-
-
-/**
- * @private
- * @brief Compares 2 strings for the specified length, and returns FF_TRUE is they are identical
- * otherwise FF_FALSE is returned.
- *
- **/
-
-#ifndef FF_UNICODE_SUPPORT
-FF_T_BOOL FF_strmatch(const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16 len) {
- register FF_T_UINT16 i;
- register FF_T_INT8 char1, char2;
-
- if(!len) {
- if(strlen(str1) != strlen(str2)) {
- return FF_FALSE;
- }
- len = (FF_T_UINT16) strlen(str1);
- }
-
- for(i = 0; i < len; i++) {
- char1 = str1[i];
- char2 = str2[i];
- if(char1 >= 'A' && char1 <= 'Z') {
- char1 += 32;
- }
- if(char2 >= 'A' && char2 <= 'Z') {
- char2 += 32;
- }
-
- if(char1 != char2) {
- return FF_FALSE;
- }
- }
-
- return FF_TRUE;
-}
-#else
-
-FF_T_BOOL FF_strmatch(const FF_T_WCHAR *str1, const FF_T_WCHAR *str2, FF_T_UINT16 len) {
- register FF_T_UINT16 i;
- register FF_T_WCHAR char1, char2;
-
- if(!len) {
- if(wcslen(str1) != wcslen(str2)) {
- return FF_FALSE;
- }
- len = (FF_T_UINT16) wcslen(str1);
- }
-
- for(i = 0; i < len; i++) {
- char1 = towlower(str1[i]);
- char2 = towlower(str2[i]);
- if(char1 != char2) {
- return FF_FALSE;
- }
- }
-
- return FF_TRUE;
-}
-#endif
-
-/**
- * @private
- * @brief A re-entrant Strtok function. No documentation is provided :P
- * Use at your own risk. (This is for FullFAT's use only).
- **/
-
-#ifndef FF_UNICODE_SUPPORT
-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) {
- FF_T_UINT16 strLen = Length;
- FF_T_UINT16 i,y, tokenStart, tokenEnd = 0;
-
- i = 0;
- y = 0;
-
- if(string[i] == '\\' || string[i] == '/') {
- i++;
- }
-
- tokenStart = i;
-
- while(i < strLen) {
- if(string[i] == '\\' || string[i] == '/') {
- y++;
- if(y == *tokenNumber) {
- tokenStart = (FF_T_UINT16)(i + 1);
- }
- if(y == (*tokenNumber + 1)) {
- tokenEnd = i;
- break;
- }
- }
- i++;
- }
-
- if(!tokenEnd) {
- if(*last == FF_TRUE) {
- return NULL;
- } else {
- *last = FF_TRUE;
- }
- tokenEnd = i;
- }
- if((tokenEnd - tokenStart) < FF_MAX_FILENAME) {
- memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart));
- token[tokenEnd - tokenStart] = '\0';
- } else {
- memcpy(token, (string + tokenStart), (FF_T_UINT32)(FF_MAX_FILENAME));
- token[FF_MAX_FILENAME-1] = '\0';
- }
- //token[tokenEnd - tokenStart] = '\0';
- *tokenNumber += 1;
-
- return token;
-}
-
-#else
-FF_T_WCHAR *FF_strtok(const FF_T_WCHAR *string, FF_T_WCHAR *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length) {
- FF_T_UINT16 strLen = Length;
- FF_T_UINT16 i,y, tokenStart, tokenEnd = 0;
-
- i = 0;
- y = 0;
-
- if(string[i] == '\\' || string[i] == '/') {
- i++;
- }
-
- tokenStart = i;
-
- while(i < strLen) {
- if(string[i] == '\\' || string[i] == '/') {
- y++;
- if(y == *tokenNumber) {
- tokenStart = (FF_T_UINT16)(i + 1);
- }
- if(y == (*tokenNumber + 1)) {
- tokenEnd = i;
- break;
- }
- }
- i++;
- }
-
- if(!tokenEnd) {
- if(*last == FF_TRUE) {
- return NULL;
- } else {
- *last = FF_TRUE;
- }
- tokenEnd = i;
- }
- if((tokenEnd - tokenStart) < FF_MAX_FILENAME) {
- memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart) * sizeof(FF_T_WCHAR));
- token[tokenEnd - tokenStart] = '\0';
- } else {
- memcpy(token, (string + tokenStart), (FF_T_UINT32)(FF_MAX_FILENAME) * sizeof(FF_T_WCHAR));
- token[FF_MAX_FILENAME-1] = '\0';
- }
- //token[tokenEnd - tokenStart] = '\0';
- *tokenNumber += 1;
-
- return token;
-}
-#endif
-
-/*
- A Wild-Card Comparator Library function, Provided by Adam Fullerton.
- This can be extended or altered to improve or advance wildCard matching
- of the FF_FindFirst() and FF_FindNext() API's.
-*/
-#ifdef FF_FINDAPI_ALLOW_WILDCARDS
-/*FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString) {
- // Check to see if the string contains the wild card
- if (!memchr(pszWildCard, '*', strlen(pszWildCard)))
- {
- // if it does not then do a straight string compare
- if (strcmp(pszWildCard, pszString))
- {
- return FF_FALSE;
- }
- }
- else
- {
- while ((*pszWildCard)
- && (*pszString))
- {
- // Test for the wild card
- if (*pszWildCard == '*')
- {
- // Eat more than one
- while (*pszWildCard == '*')
- {
- pszWildCard++;
- }
- // If there are more chars in the string
- if (*pszWildCard)
- {
- // Search for the next char
- pszString = memchr(pszString, (int)*pszWildCard, strlen(pszString));
- // if it does not exist then the strings don't match
- if (!pszString)
- {
- return FF_FALSE;
- }
-
- }
- else
- {
- if (*pszWildCard)
- {
- // continue
- break;
- }
- else
- {
- return FF_TRUE;
- }
- }
- }
- else
- {
- // Fail if they don't match
- if (*pszWildCard != *pszString)
- {
- return FF_FALSE;
- }
- }
- // Bump both pointers
- pszWildCard++;
- pszString++;
- }
- // fail if different lengths
- if (*pszWildCard != *pszString)
- {
- return FF_FALSE;
- }
- }
-
- return FF_TRUE;
-}*/
-/*
- This is a better Wild-card compare function, that works perfectly, and is much more efficient.
- This function was contributed by one of our commercial customers.
-*/
-#ifdef FF_UNICODE_SUPPORT
-FF_T_BOOL FF_wildcompare(const FF_T_WCHAR *pszWildCard, const FF_T_WCHAR *pszString) {
- register const FF_T_WCHAR *pszWc = NULL;
- register const FF_T_WCHAR *pszStr = NULL; // Encourage the string pointers to be placed in memory.
- do {
- if ( *pszWildCard == '*' ) {
- while(*(1 + pszWildCard++) == '*'); // Eat up multiple '*''s
- pszWc = (pszWildCard - 1);
- pszStr = pszString;
- }
- if (*pszWildCard == '?' && !*pszString) {
- return FF_FALSE; // False when the string is ended, yet a ? charachter is demanded.
- }
-#ifdef FF_WILDCARD_CASE_INSENSITIVE
- if (*pszWildCard != '?' && tolower(*pszWildCard) != tolower(*pszString)) {
-#else
- if (*pszWildCard != '?' && *pszWildCard != *pszString) {
-#endif
- if (pszWc == NULL) {
- return FF_FALSE;
- }
- pszWildCard = pszWc;
- pszString = pszStr++;
- }
- } while ( *pszWildCard++ && *pszString++ );
-
- while(*pszWildCard == '*') {
- pszWildCard++;
- }
-
- if(!*(pszWildCard - 1)) { // WildCard is at the end. (Terminated)
- return FF_TRUE; // Therefore this must be a match.
- }
-
- return FF_FALSE; // If not, then return FF_FALSE!
-}
-#else
-FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString) {
- register const FF_T_INT8 *pszWc = NULL;
- register const FF_T_INT8 *pszStr = NULL; // Encourage the string pointers to be placed in memory.
- do {
- if ( *pszWildCard == '*' ) {
- while(*(1 + pszWildCard++) == '*'); // Eat up multiple '*''s
- pszWc = (pszWildCard - 1);
- pszStr = pszString;
- }
- if (*pszWildCard == '?' && !*pszString) {
- return FF_FALSE; // False when the string is ended, yet a ? charachter is demanded.
- }
-#ifdef FF_WILDCARD_CASE_INSENSITIVE
- if (*pszWildCard != '?' && tolower(*pszWildCard) != tolower(*pszString)) {
-#else
- if (*pszWildCard != '?' && *pszWildCard != *pszString) {
-#endif
- if (pszWc == NULL) {
- return FF_FALSE;
- }
- pszWildCard = pszWc;
- pszString = pszStr++;
- }
- } while ( *pszWildCard++ && *pszString++ );
-
- while(*pszWildCard == '*') {
- pszWildCard++;
- }
-
- if(!*(pszWildCard - 1)) { // WildCard is at the end. (Terminated)
- return FF_TRUE; // Therefore this must be a match.
- }
-
- return FF_FALSE; // If not, then return FF_FALSE!
-}
-#endif
-
-#endif