📄 string.c
字号:
//!
//! This function is used to set the language identifier for the strings
//! returned by the GrStringGet() function. The \e usLangID parameter should
//! match one of the identifiers that was included in the string table. These
//! are provided in a header file in the graphics library and must match the
//! values that were passed through the sting compression utility.
//!
//! \return This function returns 0 if the language was not found and a
//! non-zero value if the laguage was found.
//
//*****************************************************************************
unsigned long
GrStringLanguageSet(unsigned short usLangID)
{
int iLang;
//
// Search for the requested language.
//
for(iLang = 0; iLang < g_usNumLanguages; iLang++)
{
//
// Once found, break out and save the new language.
//
if(g_pusLanguageTable[iLang] == usLangID)
{
break;
}
}
//
// Only accept the language if it was found, otherwise continue using
// previous language.
//
if(iLang != g_usNumLanguages)
{
g_usLanguage = iLang;
return(1);
}
return(0);
}
//*****************************************************************************
//
//! This function returns a string from the current string table.
//!
//! \param iIndex is the index of the string to retrieve.
//! \param pcData is the pointer to the buffer to store the string into.
//! \param ulSize is the size of the buffer provided by pcData.
//!
//! This function will return a string from the string table in the language
//! set by the GrStringLanguageSet() function. The value passed in \e iIndex
//! parameter is the string that is being requested and will be returned in
//! the buffer provided in the \e pcData parameter. The amount of data
//! returned will be limited by the ulSize parameter.
//!
//! \return Returns the number of valid bytes returned in the \e pcData buffer.
//
//*****************************************************************************
unsigned long
GrStringGet(int iIndex, char *pcData, unsigned long ulSize)
{
unsigned long ulLen, ulOffset, ulSubCode[16];
int iPos, iIdx, iBit, iSkip, iBuf;
unsigned char *pucBufferOut;
const unsigned char *pucString;
ASSERT(iIndex < g_usNumStrings);
ASSERT(pcData != 0);
//
// Initialize the output buffer state.
//
iPos = 0;
pucBufferOut = 0;
//
// if built up from another string, we need to process that
// this could nest multiple layers, so we follow in
//
ulSubCode[iPos] = g_pulStringTable[(g_usLanguage * g_usNumStrings) +
iIndex];
if(SC_GET_LEN(ulSubCode[iPos]))
{
//
// recurse down
//
while(iPos < 16)
{
//
// Copy over the partial (if any) from a previous string.
//
iIdx = SC_GET_INDEX(ulSubCode[iPos++]);
ulSubCode[iPos] = g_pulStringTable[(g_usLanguage *
g_usNumStrings) + iIdx];
if(!SC_GET_LEN(ulSubCode[iPos]))
{
//
// not linked, just string
//
break;
}
}
}
//
// Now work backwards out.
//
iIdx = 0;
//
// Build up the string in pieces.
//
while(iPos >= 0)
{
//
// Get the offset in string table.
//
ulOffset = SC_GET_OFF(ulSubCode[iPos]);
if(ulOffset == SC_IS_NULL)
{
//
// An empty string.
//
pcData[iIdx] = 0;
}
else if(ulOffset & SC_FLAG_COMPRESSED)
{
//
// This is a compressed string so initialize the pointer to the
// compressed data.
//
pucString = g_pucStringData + (ulOffset & SC_OFFSET_M);
//
// Initialize the bit variables.
//
iBit = 0;
iSkip = 0;
//
// Make a pointer to the current buffer out location.
//
pucBufferOut = (unsigned char *)pcData + iIdx;
//
// If the out buffer is beyond the maximum size then just break
// out and return what we have so far.
//
if((char *)pucBufferOut > (pcData + ulSize))
{
break;
}
//
// Now build up real string by decompressing bits.
//
if(!SC_GET_LEN(ulSubCode[iPos]) && SC_GET_INDEX(ulSubCode[iPos]))
{
iSkip = SC_GET_INDEX(ulSubCode[iPos]);
if(iPos)
{
ulLen = SC_GET_LEN(ulSubCode[iPos-1]);
}
else
{
ulLen = (iSkip & 0x3f);
}
iSkip >>= 6;
iIdx += ulLen;
ulLen += iSkip;
}
else if(iPos)
{
//
// Get the length of the partial string.
//
ulLen = SC_GET_LEN(ulSubCode[iPos-1]) - iIdx;
iIdx += ulLen;
}
else if(!SC_GET_LEN(ulSubCode[0]) && SC_GET_INDEX(ulSubCode[0]))
{
ulLen = SC_GET_INDEX(ulSubCode[0]);
iSkip = ulLen >> 6;
ulLen = (ulLen & 0x3f) + iSkip;
}
else
{
//
// Arbitrary as null character ends the string.
//
ulLen = 1024;
}
for(; ulLen; ulLen--)
{
//
// Packed 6 bits for each char
//
*pucBufferOut = (*pucString >> iBit) & 0x3f;
if(iBit >= 2)
{
*pucBufferOut |= (*++pucString << (8-iBit)) & 0x3f;
}
iBit = (iBit + 6) & 0x7;
if(!*pucBufferOut)
{
//
// end of string
//
break;
}
if(iSkip)
{
iSkip--;
continue;
}
//
// Put back removed bit
//
*pucBufferOut |= 0x40;
//
// Now look for a few special chars we mapped up into other
// characters.
//
if(*pucBufferOut == '`')
{
*pucBufferOut = ' ';
}
else if(*pucBufferOut == '~')
{
*pucBufferOut = '-';
}
else if(*pucBufferOut == 0x7f)
{
*pucBufferOut = '.';
}
else if(*pucBufferOut == '\\')
{
*pucBufferOut = ':';
}
//
// Increment the pointer and break out if the pointer is now
// beyond the end of the buffer provided.
//
pucBufferOut++;
if((char *)pucBufferOut >= (pcData + ulSize))
{
break;
}
}
}
else if(iPos)
{
//
// Part of another string
//
ulLen = SC_GET_LEN(ulSubCode[iPos - 1]) - iIdx;
//
// Prevent this copy from going beyond the end of the buffer
// provided.
//
if((iIdx + ulLen) > ulSize)
{
ulLen = ulSize - iIdx;
}
//
// Copy this portion of the string to the output buffer.
//
for(iBuf = 0; iBuf < ulLen; iBuf++)
{
pcData[iIdx + iBuf] = g_pucStringData[ulOffset + iBuf];
}
iIdx += ulLen;
}
else if(SC_GET_INDEX(ulSubCode[0]) && !SC_GET_LEN(ulSubCode[0]))
{
//
// Copy this portion of the string to the output buffer.
//
for(iBuf = 0; iBuf < SC_GET_INDEX(ulSubCode[0]); iBuf++)
{
if((iIdx + iBuf) < ulSize)
{
pcData[iIdx + iBuf] = g_pucStringData[ulOffset + iBuf];
}
else
{
break;
}
}
}
else
{
//
// The last piece is the string ending
//
for(iBuf = 0; iBuf < (ulSize - iIdx); iBuf++)
{
//
// Copy the string to the output buffer.
//
pcData[iIdx + iBuf] = g_pucStringData[ulOffset + iBuf];
//
// If a null is hit then terminate the copy.
//
if(pcData[iIdx + iBuf] == 0)
{
break;
}
}
}
iPos--;
}
//
// Return the number of bytes copied into the output buffer.
//
if(pucBufferOut)
{
ulLen = ((unsigned long)pucBufferOut - (unsigned long)pcData);
//
// Null terminate the string if there is room.
//
if(ulLen < ulSize)
{
pcData[ulLen] = 0;
}
}
else
{
ulLen = 0;
}
return(ulLen);
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -