1// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "core/include/fxcrt/fx_string.h"
8#include "unicodenormalizationdata.h"
9
10const FX_WCHAR* const g_UnicodeData_Normalization_Maps[5] = {
11    nullptr,
12    g_UnicodeData_Normalization_Map1,
13    g_UnicodeData_Normalization_Map2,
14    g_UnicodeData_Normalization_Map3,
15    g_UnicodeData_Normalization_Map4};
16
17FX_STRSIZE FX_Unicode_GetNormalization(FX_WCHAR wch, FX_WCHAR* pDst) {
18  wch = wch & 0xFFFF;
19  FX_WCHAR wFind = g_UnicodeData_Normalization[wch];
20  if (!wFind) {
21    if (pDst) {
22      *pDst = wch;
23    }
24    return 1;
25  }
26  if (wFind >= 0x8000) {
27    wch = wFind - 0x8000;
28    wFind = 1;
29  } else {
30    wch = wFind & 0x0FFF;
31    wFind >>= 12;
32  }
33  const FX_WCHAR* pMap = g_UnicodeData_Normalization_Maps[wFind];
34  if (pMap == g_UnicodeData_Normalization_Map4) {
35    pMap = g_UnicodeData_Normalization_Map4 + wch;
36    wFind = (FX_WCHAR)(*pMap++);
37  } else {
38    pMap += wch;
39  }
40  if (pDst) {
41    FX_WCHAR n = wFind;
42    while (n--) {
43      *pDst++ = *pMap++;
44    }
45  }
46  return (FX_STRSIZE)wFind;
47}
48FX_STRSIZE FX_WideString_GetNormalization(const CFX_WideStringC& wsSrc,
49                                          FX_WCHAR* pDst) {
50  FX_STRSIZE nCount = 0;
51  for (FX_STRSIZE len = 0; len < wsSrc.GetLength(); len++) {
52    FX_WCHAR wch = wsSrc.GetAt(len);
53    if (pDst) {
54      nCount += FX_Unicode_GetNormalization(wch, pDst + nCount);
55    } else {
56      nCount += FX_Unicode_GetNormalization(wch, pDst);
57    }
58  }
59  return nCount;
60}
61FX_STRSIZE FX_WideString_GetNormalization(const CFX_WideStringC& wsSrc,
62                                          CFX_WideString& wsDst) {
63  FX_STRSIZE nLen = FX_WideString_GetNormalization(wsSrc, (FX_WCHAR*)NULL);
64  if (!nLen) {
65    return 0;
66  }
67  FX_WCHAR* pBuf = wsDst.GetBuffer(nLen);
68  FX_WideString_GetNormalization(wsSrc, pBuf);
69  wsDst.ReleaseBuffer(nLen);
70  return nLen;
71}
72