git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@482 0109f412-320b-0410-ab79-c3e0c5ffbbe6
175 lines
4.6 KiB
C++
175 lines
4.6 KiB
C++
//------------------------------------------------------------------------------
|
|
// Desc: Routines for building collation keys
|
|
//
|
|
// Tabs: 3
|
|
//
|
|
// Copyright (c) 1993-2006 Novell, Inc. All Rights Reserved.
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of version 2 of the GNU General Public
|
|
// License as published by the Free Software Foundation.
|
|
//
|
|
// 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, contact Novell, Inc.
|
|
//
|
|
// To contact Novell about this file by physical or electronic mail,
|
|
// you may find current contact information at www.novell.com
|
|
//
|
|
// $Id$
|
|
//------------------------------------------------------------------------------
|
|
|
|
#include "flaimsys.h"
|
|
|
|
/**************************************************************************
|
|
Desc: Get the Flaim collating string and convert back to a text string
|
|
Ret: Length of new wpStr
|
|
Notes: Allocates the area for the word string buffer if will be over 256.
|
|
***************************************************************************/
|
|
RCODE flmColText2StorageText(
|
|
const FLMBYTE * pucColStr, // Points to the collated string
|
|
FLMUINT uiColStrLen, // Length of the collated string
|
|
FLMBYTE * pucStorageBuf, // Output string to build - TEXT string
|
|
FLMUINT * puiStorageLen, // In: Size of buffer, Out: Bytes used
|
|
FLMUINT uiLang,
|
|
FLMBOOL * pbDataTruncated, // Sets to TRUE if data had been truncated
|
|
FLMBOOL * pbFirstSubstring) // Sets to TRUE if first substring
|
|
{
|
|
#define LOCAL_CHARS 150
|
|
FLMBYTE ucWPStr[ LOCAL_CHARS * 2 + LOCAL_CHARS / 5 ]; // Sample + 20%
|
|
FLMBYTE * pucWPPtr = NULL;
|
|
FLMBYTE * pucAllocatedWSPtr = NULL;
|
|
FLMUINT uiWPStrLen;
|
|
FLMBYTE * pucStoragePtr;
|
|
FLMUINT uiUnconvChars;
|
|
FLMUINT uiTmp;
|
|
FLMUINT uiMaxStorageBytes = *puiStorageLen;
|
|
FLMUINT uiMaxWPBytes;
|
|
FLMUINT uiStorageOffset;
|
|
FLMBYTE ucTmpSen[ 5];
|
|
FLMBYTE * pucTmpSen = &ucTmpSen[ 0];
|
|
RCODE rc = NE_FLM_OK;
|
|
|
|
if( uiColStrLen > LOCAL_CHARS)
|
|
{
|
|
// If it won't fit, allocate a new buffer
|
|
|
|
if( RC_BAD( rc = f_alloc( SFLM_MAX_KEY_SIZE * 2, &pucWPPtr)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
pucAllocatedWSPtr = pucWPPtr;
|
|
uiMaxWPBytes = uiWPStrLen = SFLM_MAX_KEY_SIZE * 2;
|
|
}
|
|
else
|
|
{
|
|
pucWPPtr = &ucWPStr[ 0];
|
|
uiMaxWPBytes = uiWPStrLen = sizeof( ucWPStr);
|
|
}
|
|
|
|
if( (uiLang >= FLM_FIRST_DBCS_LANG) &&
|
|
(uiLang <= FLM_LAST_DBCS_LANG))
|
|
{
|
|
if( RC_BAD( rc = f_asiaColStr2WPStr( pucColStr, uiColStrLen,
|
|
pucWPPtr, &uiWPStrLen, &uiUnconvChars,
|
|
pbDataTruncated, pbFirstSubstring)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( RC_BAD( rc = f_colStr2WPStr( pucColStr, uiColStrLen,
|
|
pucWPPtr, &uiWPStrLen, uiLang, &uiUnconvChars,
|
|
pbDataTruncated, pbFirstSubstring)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
// Copy word string to the storage string area
|
|
|
|
uiWPStrLen >>= 1; // Convert # of bytes to # of words
|
|
pucStoragePtr = pucStorageBuf;
|
|
uiStorageOffset = 0;
|
|
|
|
// Encode the number of characters as a SEN. If pucEncPtr is
|
|
// NULL, the caller is only interested in the length of the encoded
|
|
// string, so a temporary buffer is used to call f_encodeSEN.
|
|
|
|
uiTmp = f_encodeSEN( uiWPStrLen - uiUnconvChars, &pucTmpSen);
|
|
if( (uiStorageOffset + uiTmp) >= uiMaxStorageBytes)
|
|
{
|
|
rc = RC_SET( NE_FLM_CONV_DEST_OVERFLOW);
|
|
goto Exit;
|
|
}
|
|
f_memcpy( pucStoragePtr, &ucTmpSen[ 0], uiTmp);
|
|
uiStorageOffset += uiTmp;
|
|
|
|
// Encode each of the WP characters into UTF-8
|
|
|
|
while( uiWPStrLen--)
|
|
{
|
|
FLMBYTE ucChar;
|
|
FLMBYTE ucCharSet;
|
|
FLMUNICODE uChar;
|
|
|
|
// Put the character in a local variable for speed
|
|
|
|
ucChar = *pucWPPtr++;
|
|
ucCharSet = *pucWPPtr++;
|
|
|
|
if( ucCharSet == 0xFF && ucChar == 0xFF)
|
|
{
|
|
uChar = (((FLMUNICODE)*(pucWPPtr + 1)) << 8) | *pucWPPtr;
|
|
pucWPPtr += 2;
|
|
uiWPStrLen--; // Skip past 4 bytes for UNICODE
|
|
}
|
|
else
|
|
{
|
|
if( RC_BAD( rc = f_wpToUnicode(
|
|
(((FLMUINT16)ucCharSet) << 8) + ucChar, &uChar)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
uiTmp = uiMaxStorageBytes - uiStorageOffset;
|
|
if( RC_BAD( rc = f_uni2UTF8( uChar,
|
|
&pucStorageBuf[ uiStorageOffset], &uiTmp)))
|
|
{
|
|
goto Exit;
|
|
}
|
|
uiStorageOffset += uiTmp;
|
|
}
|
|
|
|
if( uiStorageOffset >= uiMaxStorageBytes)
|
|
{
|
|
rc = RC_SET( NE_FLM_CONV_DEST_OVERFLOW);
|
|
goto Exit;
|
|
}
|
|
|
|
// Tack on a trailing NULL byte
|
|
|
|
pucStorageBuf[ uiStorageOffset++] = 0;
|
|
|
|
// Return the length of the storage buffer
|
|
|
|
*puiStorageLen = uiStorageOffset;
|
|
|
|
Exit:
|
|
|
|
if( pucAllocatedWSPtr)
|
|
{
|
|
f_free( &pucAllocatedWSPtr);
|
|
}
|
|
|
|
return( rc);
|
|
}
|
|
|