⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxstrfmt.cpp

📁 linux下的一款播放器
💻 CPP
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: hxstrfmt.cpp,v 1.7.28.3 2004/07/09 01:45:59 hubbe Exp $ *  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. *  * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks.  You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL.  Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. *  * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. *  * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. *  * Technology Compatibility Kit Test Suite(s) Location: *    http://www.helixcommunity.org/content/tck *  * Contributor(s): *  * ***** END LICENSE BLOCK ***** */#include "hxstring.h"#include "hxassert.h"#include "hlxclib/string.h"#include "safestring.h"#include "hlxclib/stdarg.h"#include "hxassert.h"static const int AlternateFlag   = 0x01;static const int ZeroPadFlag     = 0x02;static const int LeftJustifyFlag = 0x04;static const int AddSpaceFlag    = 0x08;static const int AddSignFlag     = 0x10;static const int MaxWidthSize = 12;static const int WidthParam = -2;static const int WidthError = -3;static const int MaxPrecisionSize = 12;static const int NoPrecision    = -1;static const int PrecisionParam = -2;static const int PrecisionError = -3;static const int NoLength = 0;static const int ShortLength = 1;static const int LongLength = 2;static const int MaxConversionSize = 32;static const int MaxFormatSize = 11;static int GetFlags(const char*& pCur){    int ret = 0;    for (; *pCur && strchr("#0- +", *pCur); pCur++)    {	switch(*pCur) {	case '#':	    ret |= AlternateFlag;	    break;	case '0':	    ret |= ZeroPadFlag;	    break;	case '-':	    ret |= LeftJustifyFlag;	    break;	case ' ':	    ret |= AddSpaceFlag;	    break;	    	case '+':	    ret |= AddSignFlag;	    break;	};    }    return ret;}static int GetWidth(const char*& pCur){    int ret = 1;    if (*pCur)    {	if (*pCur == '*')	{	    // The width is specified as a parameter	    pCur++;	    ret = WidthParam;	}	else	{	    if (strchr("123456789", *pCur))	    {		int i = 0;		char widthBuf[MaxWidthSize]; /* Flawfinder: ignore */				widthBuf[i++] = *pCur++;		for(; (i < MaxWidthSize) && 			*pCur && (strchr("0123456789", *pCur)); i++)		    widthBuf[i] = *pCur++;		if (i != MaxWidthSize)		{		    widthBuf[i] = '\0';		    char* pEnd = 0;		    long int tmp = strtol(widthBuf, &pEnd, 10);		    		    if (widthBuf[0] && !*pEnd)			ret = (int)tmp;		}		else		    ret = WidthError;	    }	}    }    return ret;}static int GetPrecision(const char*& pCur){    int ret = NoPrecision;    if (*pCur == '.')    {	pCur++;	if (*pCur == '*')	{	    // The width is specified as a parameter	    pCur++;	    ret = PrecisionParam;	}	else	{	    int i = 0;	    char precisionBuf[MaxPrecisionSize]; /* Flawfinder: ignore */	    	    for(; (i < MaxPrecisionSize) && 		    *pCur && (strchr("0123456789", *pCur)); i++)		precisionBuf[i] = *pCur++;	    	    if (i != MaxPrecisionSize)	    {		precisionBuf[i] = '\0';	    		if (strlen(precisionBuf))		{		    char* pEnd = 0;		    long int tmp = strtol(precisionBuf, &pEnd, 10);		    		    if (precisionBuf[0] && !*pEnd)			ret = (int)tmp;		}		else		    ret = 0;	    }	    else		ret = PrecisionError;	}    }    return ret;}static int GetLength(const char*& pCur){    int ret = NoLength;    switch(*pCur) {    case 'l':	ret = LongLength;	pCur++;	break;    case 'h':	ret = ShortLength;	pCur++;	break;    };    return ret;}static void ConstructFormat(char* fmt, char type, int flags, int length,			    int precision){    int i = 0;    fmt[i++] = '%';    if (flags & AlternateFlag)	fmt[i++] = '#';    if (flags & LeftJustifyFlag)	fmt[i++] = '-';    if (flags & AddSpaceFlag)	fmt[i++] = ' ';    if (flags & AddSignFlag)	fmt[i++] = '+';    if (flags & ZeroPadFlag)	fmt[i++] = '0';    fmt[i++] = '*';    if (precision != NoPrecision)    {	fmt[i++] = '.';	fmt[i++] = '*';    }    if (length == ShortLength)	fmt[i++] = 'h';        if (length == LongLength)	fmt[i++] = 'l';    fmt[i++] = type;    fmt[i] = '\0';    HX_ASSERT(i < MaxFormatSize);}// This could be handled with a single template function, but for now// we can't use templates. :( // I'll use a macro instead.#define CONVERT_FUNC_DEF(funcName, convertType)                    \static int funcName(const char* fmt,                               \                    int width, int precision,                      \                    convertType value)                             \{                                                                  \    int ret = 0;                                                   \    int bufSize = width + MaxConversionSize;                       \                                                                   \    if (precision != NoPrecision)                                  \        bufSize += precision;                                      \    char* pBuf = new char[bufSize];                                \    if (precision == NoPrecision)                                  \	ret = SafeSprintf(pBuf, bufSize, fmt, width, value);       \    else                                                           \	ret = SafeSprintf(pBuf, bufSize, fmt, width, precision, value); \    HX_ASSERT(ret < bufSize);                                      \    delete [] pBuf;                                                \    return ret;                                                    \}CONVERT_FUNC_DEF(ConvertInt, int)CONVERT_FUNC_DEF(ConvertShort, short int)CONVERT_FUNC_DEF(ConvertLong, long int)CONVERT_FUNC_DEF(ConvertUInt, unsigned int)CONVERT_FUNC_DEF(ConvertUShort, unsigned short int)CONVERT_FUNC_DEF(ConvertULong, unsigned long int)CONVERT_FUNC_DEF(ConvertDouble, double)CONVERT_FUNC_DEF(ConvertChar, char)CONVERT_FUNC_DEF(ConvertWChar, wchar_t)CONVERT_FUNC_DEF(ConvertPtr, void*)static bool ParseFormat(const char*& pCur, int& charCount, va_list& args){    bool ret = true;    const char* pTmp = pCur;    int flags = GetFlags(pTmp);    int width = 1;    int precision = NoPrecision;    int convertSize = 0;    if ((width = GetWidth(pTmp)) == WidthError)    {	HX_ASSERT(!fprintf(stderr, "Width field too long '%s'\n", pCur));	ret = false;    }    else if ((precision = GetPrecision(pTmp)) == PrecisionError)    {	HX_ASSERT(!fprintf(stderr, "Precision field too long '%s'\n", pCur));	ret = false;    }    else    {	int length = GetLength(pTmp);	char type = *pTmp++;	if (width == WidthParam)	{	    width = va_arg(args, int);	    if (width < 0)	    {		width = -width;		flags |= LeftJustifyFlag;	    }	}	if (precision == PrecisionParam)	{	    precision = va_arg(args, int);	    if (precision < 0)		precision = 0;	}	switch (type) {	case 's':	{	    const char* pVal = va_arg(args, const char*);	    if (length == LongLength)	    {		HX_ASSERT(!"Wide characters not supported");		// Make up something large and hope that it's big enough		convertSize = 512;	    }	    else	    {		if (precision >= 0)		{		    for(; (convertSize < precision) && 			    pVal[convertSize]; convertSize++);		}		else		    convertSize = strlen(pVal);	    }	}break;	case 'd':	case 'i':	{	    char fmt[MaxFormatSize]; /* Flawfinder: ignore */	    ConstructFormat(fmt, type, flags, length, precision);	    if (length == LongLength)	    {		long int val = va_arg(args, long int);		convertSize = ConvertLong(fmt, width, precision, val);	    }	    else if (length == ShortLength)	    {		short int val = va_arg(args, int);		convertSize = ConvertShort(fmt, width, precision, val);	    }	    else	    {		int val = va_arg(args, int);		convertSize = ConvertInt(fmt, width, precision, val);;	    }	}break;	case 'u':	case 'o':	case 'x':	case 'X':	{	    char fmt[MaxFormatSize]; /* Flawfinder: ignore */	    ConstructFormat(fmt, type, flags, length, precision);	    if (length == LongLength)	    {		unsigned long int val = va_arg(args, unsigned long int);		convertSize = ConvertULong(fmt, width, precision, val);	    }	    else if (length == ShortLength)	    {		unsigned short int val = va_arg(args, unsigned int);		convertSize = ConvertUShort(fmt, width, precision, val);	    }	    else	    {		unsigned int val = va_arg(args, unsigned int);		convertSize = ConvertUInt(fmt, width, precision, val);	    }	}break;	case 'e':	case 'E':	case 'f':	case 'g':	case 'G':	{	    char fmt[MaxFormatSize]; /* Flawfinder: ignore */	    ConstructFormat(fmt, type, flags, length, precision);	    double val = va_arg(args, double);	    convertSize = ConvertDouble(fmt, width, precision, val);	}break;	case 'c':	{	    char fmt[MaxFormatSize]; /* Flawfinder: ignore */	    ConstructFormat(fmt, type, flags, length, precision);	    if (length == LongLength)	    {		wchar_t val = va_arg(args, int);		convertSize = ConvertWChar(fmt, width, precision, val);	    }	    else	    {		char val = va_arg(args, int);		convertSize = ConvertChar(fmt, width, precision, val);	    }	}break;	case 'p':	{	    char fmt[MaxFormatSize]; /* Flawfinder: ignore */	    ConstructFormat(fmt, type, flags, length, precision);	    void* val = va_arg(args, void*);	    convertSize = ConvertPtr(fmt, width, precision, val);	}break;	case '%':	    convertSize = 1;	    break;	default:	{	    HX_ASSERT(!"Unknown format type");	    // Make up something large and hope that it's big enough	    convertSize = 512;	}break;	};	    }    if (ret)    {	charCount += (convertSize > width) ? convertSize : width;	pCur = pTmp;    }    return ret;}static int GuessSize(const char* pFormat, va_list& args){    int ret = 1;    const char* pCur = pFormat;    while(*pCur && ret != -1)    {	switch(*pCur) {	case '%':	    pCur++;	    // Handle format characters	    if (!ParseFormat(pCur, ret, args))		ret = -1;	    break;	default:	    ret++;	    pCur++;	    break;	};    }    return ret;}// This fudge factor is added to the guess to protect us// from guessing wrongstatic const int FormatFudgeFactor = 128;void CHXString::Format(const char* pFmt, ...){    va_list args;    va_start(args, pFmt);    // Guess the size    int estimatedSize = GuessSize(pFmt, args);    va_end(args);    va_start(args, pFmt);    if (m_pRep)	m_pRep->Resize(estimatedSize + FormatFudgeFactor);    else	m_pRep = new CHXStringRep(estimatedSize + FormatFudgeFactor);    int actualSize = vsnprintf(m_pRep->GetBuffer(), m_pRep->GetBufferSize(),                               pFmt, args);    HX_ASSERT(actualSize < estimatedSize);    m_pRep->SetStringSize(actualSize);    FreeExtra();    va_end(args);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -