Files
mars-flaim/xflaim/src/fcollate.cpp
ahodgkinson 12a621dc04 Changed license to LGPL.
git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@1010 0109f412-320b-0410-ab79-c3e0c5ffbbe6
2007-01-23 11:22:22 +00:00

226 lines
6.2 KiB
C++

//------------------------------------------------------------------------------
// Desc: Routines for building collation keys
// Tabs: 3
//
// Copyright (c) 1993-2007 Novell, Inc. All Rights Reserved.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version 2.1
// of the License.
//
// This library 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
// Library Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; 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 collation 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( XFLM_MAX_KEY_SIZE * 2, &pucWPPtr)))
{
goto Exit;
}
pucAllocatedWSPtr = pucWPPtr;
uiMaxWPBytes = uiWPStrLen = XFLM_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);
}
/***************************************************************************
Desc:
****************************************************************************/
RCODE F_DbSystem::compareUTF8Strings(
const FLMBYTE * pucLString,
FLMUINT uiLStrBytes,
FLMBOOL bLeftWild,
const FLMBYTE * pucRString,
FLMUINT uiRStrBytes,
FLMBOOL bRightWild,
FLMUINT uiCompareRules,
FLMUINT uiLanguage,
FLMINT * piResult)
{
return( f_compareUTF8Strings( pucLString, uiLStrBytes, bLeftWild,
pucRString, uiRStrBytes, bRightWild, uiCompareRules, uiLanguage,
piResult));
}
/***************************************************************************
Desc:
****************************************************************************/
RCODE F_DbSystem::compareUnicodeStrings(
const FLMUNICODE * puzLString,
FLMUINT uiLStrBytes,
FLMBOOL bLeftWild,
const FLMUNICODE * puzRString,
FLMUINT uiRStrBytes,
FLMBOOL bRightWild,
FLMUINT uiCompareRules,
FLMUINT uiLanguage,
FLMINT * piResult)
{
return( f_compareUnicodeStrings( puzLString, uiLStrBytes, bLeftWild,
puzRString, uiRStrBytes, bRightWild, uiCompareRules,
uiLanguage, piResult));
}
/***************************************************************************
Desc:
****************************************************************************/
RCODE FLMAPI F_DbSystem::utf8IsSubStr(
const FLMBYTE * pszString,
const FLMBYTE * pszSubString,
FLMUINT uiCompareRules,
FLMUINT uiLanguage,
FLMBOOL * pbExists)
{
return( f_utf8IsSubStr( pszString, pszSubString, uiCompareRules,
uiLanguage, pbExists));
}