| Index: arch/arm/mach-tegra/nv/nvos/nvustring.c
|
| diff --git a/arch/arm/mach-tegra/nv/nvos/nvustring.c b/arch/arm/mach-tegra/nv/nvos/nvustring.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..cc504dbe8789b19991f8d32db021313d165843d5
|
| --- /dev/null
|
| +++ b/arch/arm/mach-tegra/nv/nvos/nvustring.c
|
| @@ -0,0 +1,532 @@
|
| +/*
|
| + * Copyright (c) 2007-2009 NVIDIA Corporation.
|
| + * All rights reserved.
|
| + *
|
| + * Redistribution and use in source and binary forms, with or without
|
| + * modification, are permitted provided that the following conditions are met:
|
| + *
|
| + * Redistributions of source code must retain the above copyright notice,
|
| + * this list of conditions and the following disclaimer.
|
| + *
|
| + * Redistributions in binary form must reproduce the above copyright notice,
|
| + * this list of conditions and the following disclaimer in the documentation
|
| + * and/or other materials provided with the distribution.
|
| + *
|
| + * Neither the name of the NVIDIA Corporation nor the names of its contributors
|
| + * may be used to endorse or promote products derived from this software
|
| + * without specific prior written permission.
|
| + *
|
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
| + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
| + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
| + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
| + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
| + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
| + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
| + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
| + * POSSIBILITY OF SUCH DAMAGE.
|
| + *
|
| + */
|
| +
|
| +#include "nvutil.h"
|
| +#include "nvassert.h"
|
| +
|
| +//===========================================================================
|
| +// NvUIsdigit() - like the standard isdigit function
|
| +//===========================================================================
|
| +static int NvUIsdigit(int c)
|
| +{
|
| + return (c>='0' && c<='9');
|
| +}
|
| +
|
| +//===========================================================================
|
| +// NvUIsxdigit() - like the standard isxdigit function
|
| +//===========================================================================
|
| +static int NvUIsxdigit(int c)
|
| +{
|
| + return (c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f');
|
| +}
|
| +
|
| +//===========================================================================
|
| +// NvUCharToXDigit() - convert a hex character to its value
|
| +//===========================================================================
|
| +static int NvUCharToXDigit(int c)
|
| +{
|
| + return (c>='0' && c<='9') ? c - '0' :
|
| + (c>='a' && c<='f') ? c - 'a' + 10 :
|
| + (c>='A' && c<='F') ? c - 'A' + 10 : -1;
|
| +}
|
| +
|
| +//===========================================================================
|
| +// NvUStrtoull() - like the standard strtoull function
|
| +//===========================================================================
|
| +unsigned long long int NvUStrtoull(const char *s, char **endptr, int base)
|
| +{
|
| + int neg = 0;
|
| + unsigned long long int val = 0;
|
| +
|
| + NV_ASSERT(s);
|
| + NV_ASSERT(base==0 || base==10 || base==16);
|
| +
|
| + if (*s == '-') {
|
| + s++;
|
| + neg = 1;
|
| + }
|
| + if (s[0]=='0' && (s[1]=='x' || s[1]=='X')) {
|
| + if (base == 10) {
|
| + if (endptr) {
|
| + *endptr = (char*)s+1;
|
| + return val;
|
| + }
|
| + }
|
| + s += 2;
|
| + base = 16;
|
| + }
|
| +
|
| + if (base == 16) {
|
| + while (NvUIsxdigit(*s)) {
|
| + val <<= 4;
|
| + val += NvUCharToXDigit(*s);
|
| + s++;
|
| + }
|
| + } else {
|
| + while (NvUIsdigit(*s)) {
|
| + val *= 10;
|
| + val += NvUCharToXDigit(*s);
|
| + s++;
|
| + }
|
| + }
|
| +
|
| + if (endptr) {
|
| + *endptr = (char*)s;
|
| + }
|
| + return neg ? ((~val)+1) : val;
|
| +}
|
| +
|
| +//===========================================================================
|
| +// NvUStrtoul() - like the standard strtoul function
|
| +//===========================================================================
|
| +unsigned long int NvUStrtoul(const char *s, char **endptr, int base)
|
| +{
|
| + return (unsigned long)NvUStrtoull( s, endptr, base );
|
| +}
|
| +
|
| +//===========================================================================
|
| +// NvUStrtol() - like the standard strtol function
|
| +//===========================================================================
|
| +long int NvUStrtol(const char *s, char **endptr, int base)
|
| +{
|
| + return (long int)NvUStrtoul(s,endptr,base);
|
| +}
|
| +
|
| +//===========================================================================
|
| +// NvUStrncat() - like the standard strcat function
|
| +//===========================================================================
|
| +void NvUStrncat(char *dest, const char *src, size_t n)
|
| +{
|
| + while(*dest) dest++;
|
| + while(*src && n--) {
|
| + *(dest++) = *(src++);
|
| + }
|
| + *dest = 0;
|
| +}
|
| +
|
| +//===========================================================================
|
| +// NvUStrstr() - like the standard strstr function
|
| +//===========================================================================
|
| +char *
|
| +NvUStrstr( const char *str1, const char *str2 )
|
| +{
|
| + char s2;
|
| + NvU32 len;
|
| +
|
| + NV_ASSERT( str1 );
|
| + NV_ASSERT( str2 );
|
| +
|
| + s2 = *str2++;
|
| +
|
| + // empty string case
|
| + if (!s2) {
|
| + return (char *)str1;
|
| + }
|
| +
|
| + len = NvOsStrlen(str2);
|
| + do {
|
| + char s1;
|
| +
|
| + do {
|
| + s1 = *str1++;
|
| + if (!s1) {
|
| + return (char *)0;
|
| + }
|
| + } while (s1 != s2);
|
| + } while (NvOsStrncmp(str1, str2, len) != 0);
|
| +
|
| + return (char *)(str1 - 1);
|
| +}
|
| +
|
| +//===========================================================================
|
| +// NvUStrlConvertCodePage() - see definition in nvutil.h
|
| +// Lots of static helper functions to get/put characters in various
|
| +// code pages. For reference on the encodings, see:
|
| +// http://en.wikipedia.org/wiki/Windows-1252
|
| +// http://en.wikipedia.org/wiki/UTF-8
|
| +// http://en.wikipedia.org/wiki/UTF-16
|
| +//===========================================================================
|
| +typedef const void* (*StrGetFn)(const void*, NvU32*, size_t*);
|
| +typedef size_t (*StrPutFn)(void*, NvU32);
|
| +
|
| +static const void*
|
| +NvUStr_GetUtf8Coding(const void *pSrc,
|
| + NvU32 *Coding,
|
| + size_t *SrcSize)
|
| +{
|
| + const char *pCh = (const char *)pSrc;
|
| + NvU32 tmp = 0;
|
| + NvU8 ch;
|
| +
|
| + if (!*SrcSize)
|
| + {
|
| + *Coding = 0;
|
| + return pSrc;
|
| + }
|
| + else
|
| + {
|
| + ch = (NvU8)*pCh++;
|
| + *SrcSize = *SrcSize-1;
|
| + }
|
| +
|
| + if (*SrcSize && (ch & 0x80))
|
| + {
|
| + tmp = ((ch>>4) & 0x3);
|
| + if (tmp)
|
| + tmp--;
|
| + tmp = (ch & (0x1f>>tmp));
|
| + do
|
| + {
|
| + ch = (NvU8)*pCh++;
|
| + tmp<<=6;
|
| + tmp |= (ch & 0x3f);
|
| + *SrcSize = *SrcSize - 1;
|
| + } while (*SrcSize && ((NvU8)*pCh & 0xc0)==0x80);
|
| +
|
| + }
|
| + else
|
| + {
|
| + tmp = (NvU32)(ch&0x7f);
|
| + }
|
| +
|
| + *Coding = tmp;
|
| + return (const void *)pCh;
|
| +}
|
| +
|
| +static const void*
|
| +NvUStr_GetUtf16Coding(const void *pSrc,
|
| + NvU32 *Coding,
|
| + size_t *SrcSize)
|
| +{
|
| + const wchar_t *pCh = (const wchar_t *)pSrc;
|
| + NvU32 tmp = 0;
|
| +
|
| + if (*SrcSize<2)
|
| + {
|
| + *Coding = 0;
|
| + *SrcSize = 0;
|
| + return pSrc;
|
| + }
|
| +
|
| + tmp = (NvU32) *pCh++;
|
| + *SrcSize = *SrcSize - 2;
|
| +
|
| + if ((*SrcSize>1) && ((tmp & 0xd800UL) == 0xd800UL))
|
| + {
|
| + tmp = 0x10000UL + (((tmp & 0x3ff)<<10) | (((NvU32)*pCh++) & 0x3ffUL));
|
| + *SrcSize = *SrcSize - 2;
|
| + }
|
| +
|
| + *Coding = tmp;
|
| + return (const void *)pCh;
|
| +}
|
| +
|
| +static const NvU16 Windows1252EscapeRemapTable[32] = {
|
| + 0x20AC, 0, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
| + 0x2C26, 0x2030, 0x0160, 0x2039, 0x0152, 0, 0x017D, 0,
|
| + 0, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
| + 0x02Dc, 0x2122, 0x0161, 0x203A, 0x0153, 0, 0x017E, 0x0178 };
|
| +
|
| +static const void*
|
| +NvUStr_GetWindows1252Coding(const void *pSrc,
|
| + NvU32 *Coding,
|
| + size_t *SrcSize)
|
| +{
|
| + // the following table is used to remap windows-1252 codings 0x80-0x9f to
|
| + // the closest unicode codings. reference:
|
| + // http://en.wikipedia.org/wiki/Windows-1252
|
| +
|
| + const char *pCh = (const char *)pSrc;
|
| + NvU32 tmp;
|
| +
|
| + if (!*SrcSize)
|
| + {
|
| + *Coding = 0;
|
| + return pSrc;
|
| + }
|
| + tmp = (NvU32)*pCh++;
|
| + *SrcSize = *SrcSize - 1;
|
| +
|
| + if (tmp>=0x80 && tmp<0xA0) tmp =
|
| + (NvU32) Windows1252EscapeRemapTable[tmp-0x80];
|
| +
|
| + return (const void *) pCh;
|
| +}
|
| +
|
| +static size_t
|
| +NvUStr_PutUtf8Coding(void *pDest,
|
| + NvU32 Coding)
|
| +{
|
| + unsigned int bytes;
|
| + unsigned int i;
|
| + unsigned int mask;
|
| + unsigned int shift;
|
| + NvU8 *pCh = (NvU8 *)pDest;
|
| +
|
| + if (Coding < 0x80)
|
| + bytes = 1;
|
| + else if (Coding < 0x800UL)
|
| + bytes = 2;
|
| + else if (Coding < 0x10000UL)
|
| + bytes = 3;
|
| + else
|
| + bytes = 4;
|
| +
|
| + if (pCh)
|
| + {
|
| + mask = 0x7f;
|
| + if (bytes>1)
|
| + {
|
| + mask >>= bytes;
|
| + }
|
| + shift = (bytes-1)*6;
|
| + i = bytes;
|
| + while (i--)
|
| + {
|
| + *pCh++ = (((~((mask<<1)|1))&0xff) |
|
| + ((Coding>>shift) & mask));
|
| + shift -= 6;
|
| + mask = 0x3f;
|
| + }
|
| + }
|
| +
|
| + return (size_t)bytes;
|
| +}
|
| +
|
| +static size_t
|
| +NvUStr_PutUtf16Coding(void *pDest,
|
| + NvU32 Coding)
|
| +
|
| +{
|
| + size_t bytes = (Coding > 0x10000UL) ? 4 : 2;
|
| + NvU16 *pCh = (NvU16 *)pDest;
|
| +
|
| + if (pCh)
|
| + {
|
| + if (bytes==4)
|
| + {
|
| + Coding -= 0x10000UL;
|
| + *pCh++ = (NvU16) (0xd800UL | ((Coding>>10)&0x3ffUL));
|
| + *pCh++ = (NvU16) (0xdb00UL | (Coding & 0x3ffUL));
|
| + }
|
| + else
|
| + *pCh++ = (NvU16) (Coding & 0xffffUL);
|
| + }
|
| +
|
| + return bytes;
|
| +}
|
| +
|
| +static size_t
|
| +NvUStr_PutWindows1252Coding(void *pDest,
|
| + NvU32 Coding)
|
| +{
|
| + NvU8 *pCh = (NvU8 *)pDest;
|
| + unsigned int i;
|
| +
|
| + if (pCh)
|
| + {
|
| + if ((Coding<0x80UL) || ((Coding<0x100UL)&&(Coding>0x9FUL)))
|
| + *pCh++ = (NvU8)(Coding & 0xff);
|
| + else
|
| + {
|
| + for (i=0; i<32 && (NvU32)Windows1252EscapeRemapTable[i]!=Coding; i++) { }
|
| + *pCh++ = ((i==32) ? 0x90 : ((0x80+i) & 0xff));
|
| + }
|
| + }
|
| + return 1;
|
| +}
|
| +
|
| +size_t
|
| +NvUStrlConvertCodePage(void *pDest,
|
| + size_t DestSize,
|
| + NvOsCodePage DestCodePage,
|
| + const void *pSrc,
|
| + size_t SrcSize,
|
| + NvOsCodePage SrcCodePage)
|
| +{
|
| + StrGetFn GetChar = NULL;
|
| + StrPutFn PutChar = NULL;
|
| + char *pStr = (char *)pDest;
|
| + size_t OutputSize = 0;
|
| + size_t CodeSize = 0;
|
| + size_t Remain = SrcSize;
|
| + NvU32 Coding;
|
| +
|
| + if (!pSrc)
|
| + return 0;
|
| + // to simplify down-stream code paths, if the source is NULL-terminated
|
| + // (SrcSize==0), or the destination is NULL, set the corresponding sizes
|
| + // to ~0 (effectively infinite, since memory will be filled before the
|
| + // size limit is reached)
|
| + if (!pDest)
|
| + DestSize = (size_t)~0;
|
| + if (!Remain)
|
| + Remain = (size_t)~0;
|
| +
|
| + if (DestCodePage == NvOsCodePage_Unknown)
|
| + DestCodePage = NvOsStrGetSystemCodePage();
|
| + if (SrcCodePage == NvOsCodePage_Unknown)
|
| + SrcCodePage = NvOsStrGetSystemCodePage();
|
| +
|
| + switch (DestCodePage)
|
| + {
|
| + case NvOsCodePage_Utf8:
|
| + PutChar = NvUStr_PutUtf8Coding; break;
|
| + case NvOsCodePage_Utf16:
|
| + PutChar = NvUStr_PutUtf16Coding; break;
|
| + case NvOsCodePage_Windows1252:
|
| + PutChar = NvUStr_PutWindows1252Coding; break;
|
| + default:
|
| + NV_ASSERT(!"Unsupported destination code page");
|
| + return 0;
|
| + }
|
| +
|
| + // the NULL terminator in Unicode is 0; compute the size of the terminator
|
| + // in the destination coding by calling the PutChar routine once with
|
| + // coding zero.
|
| + OutputSize = PutChar(NULL, 0);
|
| + if (OutputSize > DestSize)
|
| + return 0;
|
| +
|
| + switch (SrcCodePage)
|
| + {
|
| + case NvOsCodePage_Utf8: GetChar =
|
| + NvUStr_GetUtf8Coding; break;
|
| + case NvOsCodePage_Utf16: GetChar =
|
| + NvUStr_GetUtf16Coding; break;
|
| + case NvOsCodePage_Windows1252: GetChar =
|
| + NvUStr_GetWindows1252Coding; break;
|
| + default:
|
| + NV_ASSERT(!"Unsupported source code page");
|
| + return 0;
|
| + }
|
| +
|
| + // optimized path for conversions of the lower 128 ASCII characters
|
| + if (( (DestCodePage == NvOsCodePage_Utf8) ||
|
| + (DestCodePage == NvOsCodePage_Windows1252)) &&
|
| + (SrcCodePage == NvOsCodePage_Utf16))
|
| + {
|
| + const NvU16 *pCh = (const NvU16 *)pSrc;
|
| + while (*pCh && (*pCh<0x80) && (OutputSize < DestSize) && Remain)
|
| + {
|
| + if (pStr)
|
| + *pStr++ = (char)*pCh;
|
| + OutputSize++;
|
| + Remain -= 2;
|
| + pCh++;
|
| + }
|
| + pSrc = (const void *)pCh;
|
| + }
|
| + else if ((DestCodePage == NvOsCodePage_Utf16) &&
|
| + ( (SrcCodePage == NvOsCodePage_Utf8) ||
|
| + (SrcCodePage == NvOsCodePage_Windows1252)))
|
| + {
|
| + const NvU8 *pCh = (const NvU8 *)pSrc;
|
| + wchar_t *pStrW = (wchar_t *)pStr;
|
| + while (*pCh && (*pCh<0x80) && (OutputSize < DestSize) && Remain)
|
| + {
|
| + if (pStrW)
|
| + *pStrW++ = (wchar_t)*pCh;
|
| + OutputSize+=2;
|
| + Remain--;
|
| + pCh++;
|
| + }
|
| + pStr = (char *)pStrW;
|
| + pSrc = (const void *)pCh;
|
| + }
|
| +
|
| + pSrc = GetChar(pSrc, &Coding, &Remain);
|
| + // All the GetChar* functions return a NULL coding when insufficient
|
| + // source bytes remain, so we don't need to check it in the loop
|
| + while (Coding)
|
| + {
|
| + CodeSize = PutChar(NULL, Coding);
|
| + if (pStr)
|
| + {
|
| + if ((OutputSize + CodeSize)<=DestSize)
|
| + {
|
| + pStr += PutChar(pStr, Coding);
|
| + OutputSize += CodeSize;
|
| + }
|
| + else
|
| + break;
|
| + }
|
| + else
|
| + OutputSize += CodeSize;
|
| +
|
| + pSrc = GetChar(pSrc, &Coding, &Remain);
|
| + }
|
| + if (pStr)
|
| + {
|
| + pStr += PutChar(pStr, 0);
|
| + }
|
| +
|
| + return OutputSize;
|
| +}
|
| +
|
| +NvU32
|
| +NvULowestBitSet( NvU32 bits, NvU32 nBits )
|
| +{
|
| + NvU32 ret = 0;
|
| +
|
| + if( nBits > 16 )
|
| + {
|
| + if( !(bits & 0xffff) )
|
| + {
|
| + ret += 16;
|
| + bits >>= 16;
|
| + }
|
| + }
|
| +
|
| + if( nBits > 8 )
|
| + {
|
| + if( !(bits & 0xff) )
|
| + {
|
| + ret += 8;
|
| + bits >>= 8;
|
| + }
|
| + }
|
| +
|
| + if( !(bits & 0xf) )
|
| + {
|
| + ret += 4;
|
| + bits >>= 4;
|
| + }
|
| +
|
| + if( !(bits & 0x3) )
|
| + {
|
| + ret += 2;
|
| + bits >>= 2;
|
| + }
|
| +
|
| + return ret + ((bits & 1) ? 0 : 1 );
|
| +}
|
|
|