mirror of https://github.com/acidanthera/audk.git
271 lines
9.0 KiB
C
271 lines
9.0 KiB
C
/** @file
|
|
Search Functions for <wchar.h>.
|
|
|
|
Unless explicitly stated otherwise, the functions defined in this file order
|
|
two wide characters the same way as two integers of the underlying integer
|
|
type designated by wchar_t.
|
|
|
|
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
|
This program and the accompanying materials are licensed and made available under
|
|
the terms and conditions of the BSD License that accompanies this distribution.
|
|
The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php.
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
**/
|
|
#include <Uefi.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
|
|
#include <LibConfig.h>
|
|
|
|
#include <wchar.h>
|
|
|
|
/* Data initialized by the library constructor */
|
|
extern UINT8 *__wchar_bitmap;
|
|
extern UINTN __wchar_bitmap_size;
|
|
extern UINTN __wchar_bitmap_64;
|
|
|
|
/** The wcschr function locates the first occurrence of c in the wide string
|
|
pointed to by s. The terminating null wide character is considered to be
|
|
part of the wide string.
|
|
|
|
@return The wcschr function returns a pointer to the located wide
|
|
character, or a null pointer if the wide character does not occur
|
|
in the wide string.
|
|
**/
|
|
wchar_t *wcschr(const wchar_t *s, wchar_t c)
|
|
{
|
|
do {
|
|
if( *s == c) {
|
|
return (wchar_t *)s;
|
|
}
|
|
} while(*s++ != 0);
|
|
return NULL;
|
|
}
|
|
|
|
static UINT8 BitMask[] = {
|
|
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
|
|
};
|
|
|
|
#define WHICH8(c) ((unsigned short)(c) >> 3)
|
|
#define WHICH_BIT(c) (BitMask[((c) & 0x7)])
|
|
#define BITMAP64 ((UINT64 *)bitmap)
|
|
|
|
static
|
|
void
|
|
BuildBitmap(unsigned char * bitmap, const wchar_t *s2, UINTN n)
|
|
{
|
|
UINT8 bit;
|
|
UINTN index;
|
|
|
|
//// Initialize bitmap. Bit 0 is always 1 which corresponds to '\0'
|
|
//for (BITMAP64[0] = index = 1; index < n; index++)
|
|
// BITMAP64[index] = 0;
|
|
(void)wmemset( (wchar_t *)bitmap, 0, n / sizeof(wchar_t));
|
|
bitmap[0] = 1;
|
|
|
|
// Set bits in bitmap corresponding to the characters in s2
|
|
for (; *s2 != 0; ++s2) {
|
|
index = WHICH8(*s2);
|
|
bit = WHICH_BIT(*s2);
|
|
bitmap[index] |= bit;
|
|
}
|
|
}
|
|
|
|
/** The wcscspn function computes the length of the maximum initial segment of
|
|
the wide string pointed to by s1 which consists entirely of wide characters
|
|
not from the wide string pointed to by s2.
|
|
|
|
@return The wcscspn function returns the length of the segment.
|
|
**/
|
|
size_t wcscspn(const wchar_t *s1, const wchar_t *s2)
|
|
{
|
|
const wchar_t *str;
|
|
UINT8 bit;
|
|
int index;
|
|
size_t s1len;
|
|
|
|
if(*s1 == 0) return 0;
|
|
s1len = wcslen(s1);
|
|
|
|
BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);
|
|
|
|
for(str = s1; str < &s1[s1len] ; str++) {
|
|
index = WHICH8(*str);
|
|
bit = WHICH_BIT(*str);
|
|
if ((__wchar_bitmap[index] & bit) != 0)
|
|
break;
|
|
}
|
|
return (str - s1);
|
|
}
|
|
|
|
/** The wcspbrk function locates the first occurrence in the wide string
|
|
pointed to by s1 of any wide character from the wide string
|
|
pointed to by s2.
|
|
|
|
@return The wcspbrk function returns a pointer to the wide character
|
|
in s1, or a null pointer if no wide character from s2 occurs
|
|
in s1.
|
|
**/
|
|
wchar_t *wcspbrk(const wchar_t *s1, const wchar_t *s2)
|
|
{
|
|
UINT8 bit;
|
|
int index;
|
|
|
|
BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);
|
|
|
|
for( ; *s1 != 0; ++s1) {
|
|
index = WHICH8(*s1);
|
|
bit = WHICH_BIT(*s1);
|
|
if( (__wchar_bitmap[index] & bit) != 0) {
|
|
return (wchar_t *)s1;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/** The wcsrchr function locates the last occurrence of c in the wide string
|
|
pointed to by s. The terminating null wide character is considered to be
|
|
part of the wide string.
|
|
|
|
@return The wcsrchr function returns a pointer to the wide character,
|
|
or a null pointer if c does not occur in the wide string.
|
|
**/
|
|
wchar_t *wcsrchr(const wchar_t *s, wchar_t c)
|
|
{
|
|
wchar_t *found = NULL;
|
|
|
|
do {
|
|
if( *s == c) found = (wchar_t *)s;
|
|
} while( *s++ != 0);
|
|
|
|
return found;
|
|
}
|
|
|
|
/** The wcsspn function computes the length of the maximum initial segment of
|
|
the wide string pointed to by s1 which consists entirely of wide characters
|
|
from the wide string pointed to by s2.
|
|
|
|
@return The wcsspn function returns the length of the segment.
|
|
**/
|
|
size_t wcsspn(const wchar_t *s1, const wchar_t *s2)
|
|
{
|
|
size_t length = 0;
|
|
int index;
|
|
UINT8 bit;
|
|
|
|
BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);
|
|
|
|
for( ; *s1 != 0; ++s1) {
|
|
index = WHICH8(*s1);
|
|
bit = WHICH_BIT(*s1);
|
|
if( (__wchar_bitmap[index] & bit) == 0) break;
|
|
++length;
|
|
}
|
|
return length;
|
|
}
|
|
|
|
/** The wcsstr function locates the first occurrence in the wide string pointed
|
|
to by s1 of the sequence of wide characters (excluding the terminating null
|
|
wide character) in the wide string pointed to by s2.
|
|
|
|
@return The wcsstr function returns a pointer to the located wide string,
|
|
or a null pointer if the wide string is not found. If s2 points
|
|
to a wide string with zero length, the function returns s1.
|
|
**/
|
|
wchar_t *wcsstr(const wchar_t *s1, const wchar_t *s2)
|
|
{
|
|
return (wchar_t *)StrStr( (CONST CHAR16 *)s1, (CONST CHAR16 *)s2);
|
|
}
|
|
|
|
/** A sequence of calls to the wcstok function breaks the wide string pointed
|
|
to by s1 into a sequence of tokens, each of which is delimited by a wide
|
|
character from the wide string pointed to by s2. The third argument points
|
|
to a caller-provided wchar_t pointer into which the wcstok function stores
|
|
information necessary for it to continue scanning the same wide string.
|
|
|
|
The first call in a sequence has a non-null first argument and stores an
|
|
initial value in the object pointed to by ptr. Subsequent calls in the
|
|
sequence have a null first argument and the object pointed to by ptr is
|
|
required to have the value stored by the previous call in the sequence,
|
|
which is then updated. The separator wide string pointed to by s2 may be
|
|
different from call to call.
|
|
|
|
The first call in the sequence searches the wide string pointed to by s1
|
|
for the first wide character that is not contained in the current separator
|
|
wide string pointed to by s2. If no such wide character is found, then
|
|
there are no tokens in the wide string pointed to by s1 and the wcstok
|
|
function returns a null pointer. If such a wide character is found, it is
|
|
the start of the first token.
|
|
|
|
The wcstok function then searches from there for a wide character that is
|
|
contained in the current separator wide string. If no such wide character
|
|
is found, the current token extends to the end of the wide string pointed
|
|
to by s1, and subsequent searches in the same wide string for a token
|
|
return a null pointer. If such a wide character is found, it is overwritten
|
|
by a null wide character, which terminates the current token.
|
|
|
|
In all cases, the wcstok function stores sufficient information in the
|
|
pointer pointed to by ptr so that subsequent calls, with a null pointer for
|
|
s1 and the unmodified pointer value for ptr, shall start searching just
|
|
past the element overwritten by a null wide character (if any).
|
|
|
|
@return The wcstok function returns a pointer to the first wide character
|
|
of a token, or a null pointer if there is no token.
|
|
**/
|
|
wchar_t *wcstok(wchar_t * __restrict s1, const wchar_t * __restrict s2, wchar_t ** __restrict ptr)
|
|
{
|
|
wchar_t *Token = NULL;
|
|
int index;
|
|
UINT8 bit;
|
|
|
|
if( (s1 == NULL)
|
|
&& ((s1 = *ptr) == NULL))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
// s2 can be different on each call, so build the bitmap each time.
|
|
BuildBitmap( __wchar_bitmap, s2, __wchar_bitmap_size);
|
|
|
|
// skip leading delimiters: all chars in s2
|
|
for( ; *s1 != 0; ++s1) {
|
|
index = WHICH8(*s1);
|
|
bit = WHICH_BIT(*s1);
|
|
if( (__wchar_bitmap[index] & bit) == 0) break;
|
|
}
|
|
if( *s1 != 0)
|
|
{
|
|
// Remember this point, it is the start of the token
|
|
Token = s1++;
|
|
|
|
// find the next delimiter and replace it with a '\0'
|
|
for( ; *s1 != 0; ++s1) {
|
|
index = WHICH8(*s1);
|
|
bit = WHICH_BIT(*s1);
|
|
if( (__wchar_bitmap[index] & bit) != 0) {
|
|
*s1++ = 0;
|
|
*ptr = s1;
|
|
return Token;
|
|
}
|
|
}
|
|
}
|
|
*ptr = NULL;
|
|
return Token;
|
|
}
|
|
|
|
/** The wmemchr function locates the first occurrence of c in the initial n
|
|
wide characters of the object pointed to by s.
|
|
|
|
@return The wmemchr function returns a pointer to the located wide
|
|
character, or a null pointer if the wide character does not occur
|
|
in the object.
|
|
**/
|
|
wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)
|
|
{
|
|
return (wchar_t *)ScanMem16( s, (UINTN)(n * sizeof(wchar_t)), (UINT16)c);
|
|
}
|