示例#1
0
NS_IMETHODIMP nsCollationMacUC::AllocateRawSortKey(int32_t strength, const nsAString& stringIn,
                                                   uint8_t** key, uint32_t* outLen)
{
  NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
  NS_ENSURE_ARG_POINTER(key);
  NS_ENSURE_ARG_POINTER(outLen);

  nsresult res = EnsureCollator(strength);
  NS_ENSURE_SUCCESS(res, res);

  uint32_t stringInLen = stringIn.Length();

  const UChar* str = (const UChar*)PromiseFlatString(stringIn).get();

  int32_t keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, nullptr, 0);
  NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE);

  // Since key is freed elsewhere with PR_Free, allocate with PR_Malloc.
  uint8_t* newKey = (uint8_t*)PR_Malloc(keyLength + 1);
  if (!newKey) {
      return NS_ERROR_OUT_OF_MEMORY;
  }

  keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, newKey, keyLength + 1);
  NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE);

  *key = newKey;
  *outLen = keyLength;

  return NS_OK;
}
示例#2
0
NS_IMETHODIMP nsCollationMacUC::CompareString(int32_t strength, const nsAString& string1,
                                              const nsAString& string2, int32_t* result)
{
  NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
  NS_ENSURE_ARG_POINTER(result);
  *result = 0;

  nsresult rv = EnsureCollator(strength);
  NS_ENSURE_SUCCESS(rv, rv);

  UCollationResult uresult;
  uresult = ucol_strcoll(mCollatorICU,
                          (const UChar*)PromiseFlatString(string1).get(), string1.Length(),
                          (const UChar*)PromiseFlatString(string2).get(), string2.Length());
  int32_t res;
  switch (uresult) {
    case UCOL_LESS:
      res = -1;
      break;
    case UCOL_EQUAL:
      res = 0;
      break;
    case UCOL_GREATER:
      res = 1;
      break;
    default:
      MOZ_CRASH("ucol_strcoll returned bad UCollationResult");
  }
  *result = res;
  return NS_OK;
}
示例#3
0
/*----------------------------------------------------------------------------------------------
	Generate the sort key as a "SAFEARRAY".
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgIcuCollator::get_SortKeyVariant(BSTR bstrValue, LgCollatingOptions colopt,
	VARIANT * psaKey)
{
	BEGIN_COM_METHOD;
	ChkComBstrArgN(bstrValue);
	ChkComArgPtr(psaKey);
	psaKey->vt = VT_NULL;

	EnsureCollator();

	int32_t cbKey = keySize;
	byte rgbKey[keySize+1];
	Vector<byte> vbKey;
	byte * pbKey = GetSortKey(bstrValue, rgbKey, &cbKey, vbKey);

	// Allocate the safe array.
	SAFEARRAYBOUND rgsabound[1];
	rgsabound[0].lLbound = 0;
	rgsabound[0].cElements = cbKey;
	SAFEARRAY FAR * psa = ::SafeArrayCreate(VT_UI1, 1, rgsabound);
	// Copy the key data to the safe array.
	byte * pbOut;
	CheckHr(::SafeArrayAccessData(psa, (void HUGEP **)&pbOut));
	memcpy(pbOut, pbKey, cbKey);
	CheckHr(::SafeArrayUnaccessData(psa));
	// Push the safe array to the output pointer.
	psaKey->vt = VT_UI1 | VT_ARRAY;
	V_ARRAY(psaKey) = psa;

	return S_OK;

	END_COM_METHOD(g_fact, IID_ILgCollatingEngine);
}
示例#4
0
/*----------------------------------------------------------------------------------------------
	Do a direct string comparison.
	Note that, contrary to what the contract implies, this routine is not more
	efficient than the client just retrieving the keys and comparing them.
	OPTIMIZE: would we benefit significantly by implementing this using CompareString?
	Unfortunately, it is hard to avoid the need to do the WideCharToMultiByte conversion
	for the whole of both strings...
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgIcuCollator::Compare(BSTR bstrValue1, BSTR bstrValue2,
	LgCollatingOptions colopt, int * pnVal)
{
	BEGIN_COM_METHOD
	ChkComBstrArgN(bstrValue1);
	ChkComBstrArgN(bstrValue2);
	ChkComOutPtr(pnVal);

	EnsureCollator();

	int32_t cbKey1 = keySize;
	byte rgbKey1[keySize+1];
	Vector<byte> vbKey1;
	byte * pbKey1 = GetSortKey(bstrValue1, rgbKey1, &cbKey1, vbKey1);

	int32_t cbKey2 = keySize;
	byte rgbKey2[keySize+1];
	Vector<byte> vbKey2;
	byte * pbKey2 = GetSortKey(bstrValue2, rgbKey2, &cbKey2, vbKey2);

	*pnVal = strcmp((char *)pbKey1, (char *)pbKey2);

	return S_OK;

	END_COM_METHOD(g_fact, IID_ILgCollatingEngine);
}
示例#5
0
/*----------------------------------------------------------------------------------------------
	Initialize the collating engine to the given locale.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgIcuCollator::Open(BSTR bstrLocale)
{
	BEGIN_COM_METHOD;
	ChkComBstrArgN(bstrLocale);

	if (m_pCollator)
	{
		delete m_pCollator;
		m_pCollator = NULL;
	}
	m_stuLocale = bstrLocale;
	EnsureCollator();
	END_COM_METHOD(g_fact, IID_ILgCollatingEngine);
}
示例#6
0
/*----------------------------------------------------------------------------------------------
	Do a direct string comparison using "SAFEARRAY"s.
	Note that, contrary to what the contract implies, this routine is not more
	efficient than the client just retrieving the keys and comparing them.
	OPTIMIZE: would we benefit significantly by implementing this using CompareString?
	Unfortunately, it is hard to avoid the need to do the WideCharToMultiByte conversion
	for the whole of both strings...
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgIcuCollator::CompareVariant(VARIANT saKey1, VARIANT saKey2,
	LgCollatingOptions colopt, int * pnVal)
{
	BEGIN_COM_METHOD;
	ChkComOutPtr(pnVal);
#if WIN32

	EnsureCollator();

	UINT cDim = ::SafeArrayGetDim(V_ARRAY(&saKey1));
	if (cDim != 1)
		return E_INVALIDARG;
	UINT cElemSize = ::SafeArrayGetElemsize(V_ARRAY(&saKey1));
	if (cElemSize != 1)
		return E_INVALIDARG;
	cDim = ::SafeArrayGetDim(V_ARRAY(&saKey2));
	if (cDim != 1)
		return E_INVALIDARG;
	cElemSize = ::SafeArrayGetElemsize(V_ARRAY(&saKey2));
	if (cElemSize != 1)
		return E_INVALIDARG;

	byte * pbKey1;
	CheckHr(::SafeArrayAccessData(V_ARRAY(&saKey1), (void HUGEP **)&pbKey1));
	byte * pbKey2;
	CheckHr(::SafeArrayAccessData(V_ARRAY(&saKey2), (void HUGEP **)&pbKey2));
	if (pbKey1 == NULL)
	{
		*pnVal = 1;
	}
	else if (pbKey2 == NULL)
	{
		*pnVal = -1;
	}
	else
	{
		*pnVal = strcmp((char *)pbKey1, (char *)pbKey2);
	}
	CheckHr(::SafeArrayUnaccessData(V_ARRAY(&saKey1)));
	CheckHr(::SafeArrayUnaccessData(V_ARRAY(&saKey2)));

	return S_OK;
#else
	// TODO-Linux: does this need porting?
	printf("Warning: using unported method LgIcuCollator::CompareVariant\n");
	fflush(stdout);
#endif //WIN32

	END_COM_METHOD(g_fact, IID_ILgCollatingEngine);
}
NS_IMETHODIMP nsCollationMacUC::AllocateRawSortKey(int32_t strength, const nsAString& stringIn,
                                                   uint8_t** key, uint32_t* outLen)
{
  NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
  NS_ENSURE_ARG_POINTER(key);
  NS_ENSURE_ARG_POINTER(outLen);

  nsresult res = EnsureCollator(strength);
  NS_ENSURE_SUCCESS(res, res);

  uint32_t stringInLen = stringIn.Length();
  uint32_t maxKeyLen = (1 + stringInLen) * kCollationValueSizeFactor * sizeof(UCCollationValue);
  if (maxKeyLen > mBufferLen) {
    uint32_t newBufferLen = mBufferLen;
    do {
      newBufferLen *= 2;
    } while (newBufferLen < maxKeyLen);
    void *newBuffer = PR_Malloc(newBufferLen);
    if (!newBuffer)
      return NS_ERROR_OUT_OF_MEMORY;

    PR_FREEIF(mBuffer);
    mBuffer = newBuffer;
    mBufferLen = newBufferLen;
  }

  ItemCount actual;
  OSStatus err = ::UCGetCollationKey(mCollator, (const UniChar*) PromiseFlatString(stringIn).get(),
                                     (UniCharCount) stringInLen,
                                     (ItemCount) (mBufferLen / sizeof(UCCollationValue)),
                                     &actual, (UCCollationValue *)mBuffer);
  NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE);

  uint32_t keyLength = actual * sizeof(UCCollationValue);
  void *newKey = PR_Malloc(keyLength);
  if (!newKey)
    return NS_ERROR_OUT_OF_MEMORY;

  memcpy(newKey, mBuffer, keyLength);
  *key = (uint8_t *)newKey;
  *outLen = keyLength;

  return NS_OK;
}
NS_IMETHODIMP nsCollationMacUC::CompareString(int32_t strength, const nsAString& string1,
                                              const nsAString& string2, int32_t* result) 
{
  NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
  NS_ENSURE_ARG_POINTER(result);
  *result = 0;

  nsresult res = EnsureCollator(strength);
  NS_ENSURE_SUCCESS(res, res);
  *result = 0;

  OSStatus err;
  err = ::UCCompareText(mCollator, 
                        (const UniChar *) PromiseFlatString(string1).get(), (UniCharCount) string1.Length(),
                        (const UniChar *) PromiseFlatString(string2).get(), (UniCharCount) string2.Length(),
                        nullptr, (SInt32*) result);

  NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE);
  return NS_OK;
}
示例#9
0
/*----------------------------------------------------------------------------------------------
	Generate the sort key as a byte *
----------------------------------------------------------------------------------------------*/
byte * LgIcuCollator::GetSortKey(BSTR bstrValue, byte* prgbKey, int32_t* pcbKey)
{
	byte * pbKey;
	int32_t crgbKey = *pcbKey;
	EnsureCollator();
	*pcbKey = m_pCollator->getSortKey(bstrValue, BstrLen(bstrValue),
		prgbKey, crgbKey);
	if (*pcbKey > crgbKey)
	{
		// sort key is too long, the caller has to pass us a bigger buffer.
		pbKey = NULL;
	}
	else
	{
		// sort key is less than 1024 bytes
		pbKey = prgbKey;
	}

	return pbKey;
}
NS_IMETHODIMP nsCollationMacUC::CompareString(int32_t strength, const nsAString& string1,
                                              const nsAString& string2, int32_t* result) 
{
  NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
  NS_ENSURE_ARG_POINTER(result);
  *result = 0;

  nsresult res = EnsureCollator(strength);
  NS_ENSURE_SUCCESS(res, res);

  if (mUseICU) {
    UCollationResult uresult;
    uresult = ucol_strcoll(mCollatorICU,
                           (const UChar*)PromiseFlatString(string1).get(), string1.Length(),
                           (const UChar*)PromiseFlatString(string2).get(), string2.Length());
    int32_t res;
    switch (uresult) {
      case UCOL_LESS: res = -1; break;
      case UCOL_EQUAL: res = 0; break;
      case UCOL_GREATER: res = 1; break;
      default: MOZ_CRASH("ucol_strcoll returned bad UCollationResult");
    }
    *result = res;
    return NS_OK;
  }

  *result = 0;

  OSStatus err;
  err = ::UCCompareText(mCollator, 
                        (const UniChar *) PromiseFlatString(string1).get(), (UniCharCount) string1.Length(),
                        (const UniChar *) PromiseFlatString(string2).get(), (UniCharCount) string2.Length(),
                        nullptr, (SInt32*) result);

  NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE);
  return NS_OK;
}
NS_IMETHODIMP nsCollationMacUC::AllocateRawSortKey(int32_t strength, const nsAString& stringIn,
                                                   uint8_t** key, uint32_t* outLen)
{
  NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
  NS_ENSURE_ARG_POINTER(key);
  NS_ENSURE_ARG_POINTER(outLen);

  nsresult res = EnsureCollator(strength);
  NS_ENSURE_SUCCESS(res, res);

  uint32_t stringInLen = stringIn.Length();

  if (mUseICU) {
    const UChar* str = (const UChar*)PromiseFlatString(stringIn).get();

    int32_t keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, nullptr, 0);
    NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE);

    // Since key is freed elsewhere with PR_Free, allocate with PR_Malloc.
    uint8_t* newKey = (uint8_t*)PR_Malloc(keyLength + 1);
    if (!newKey) {
      return NS_ERROR_OUT_OF_MEMORY;
    }

    keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, newKey, keyLength + 1);
    NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE);

    *key = newKey;
    *outLen = keyLength;

    return NS_OK;
  }

  uint32_t maxKeyLen = (1 + stringInLen) * kCollationValueSizeFactor * sizeof(UCCollationValue);
  if (maxKeyLen > mBufferLen) {
    uint32_t newBufferLen = mBufferLen;
    do {
      newBufferLen *= 2;
    } while (newBufferLen < maxKeyLen);
    void* newBuffer = moz_malloc(newBufferLen);
    if (!newBuffer) {
      return NS_ERROR_OUT_OF_MEMORY;
    }

    if (mBuffer) {
      moz_free(mBuffer);
      mBuffer = nullptr;
    }
    mBuffer = newBuffer;
    mBufferLen = newBufferLen;
  }

  ItemCount actual;
  OSStatus err = ::UCGetCollationKey(mCollator, (const UniChar*) PromiseFlatString(stringIn).get(),
                                     (UniCharCount) stringInLen,
                                     (ItemCount) (mBufferLen / sizeof(UCCollationValue)),
                                     &actual, (UCCollationValue *)mBuffer);
  NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE);

  uint32_t keyLength = actual * sizeof(UCCollationValue);
  // Since key is freed elsewhere with PR_Free, allocate with PR_Malloc.
  void* newKey = PR_Malloc(keyLength);
  if (!newKey) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

  memcpy(newKey, mBuffer, keyLength);
  *key = (uint8_t *)newKey;
  *outLen = keyLength;

  return NS_OK;
}