VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/string/utf-16-case.cpp@ 60963

Last change on this file since 60963 was 60481, checked in by vboxsync, 9 years ago

IPRT: Added testcase for RTNtPathExpand8dot3Path and RTNtPathFindPossible8dot3Name, fixing bug in the former. include\ src\VBox\Runtime\

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
  • Property svn:mergeinfo set to (toggle deleted branches)
    /branches/VBox-3.0/src/VBox/Runtime/common/string/utf-16.cpp58652,​70973
    /branches/VBox-3.2/src/VBox/Runtime/common/string/utf-16.cpp66309,​66318
    /branches/VBox-4.0/src/VBox/Runtime/common/string/utf-16.cpp70873
    /branches/VBox-4.1/src/VBox/Runtime/common/string/utf-16.cpp74233,​78414,​78691,​81841,​82127,​85941,​85944-85947,​85949-85950,​85953,​86701,​86728,​87009
    /branches/VBox-4.2/src/VBox/Runtime/common/string/utf-16.cpp86229-86230,​86234,​86529,​91503-91504,​91506-91508,​91510,​91514-91515,​91521
    /branches/VBox-4.3/src/VBox/Runtime/common/string/utf-16.cpp91223
    /branches/VBox-4.3/trunk/src/VBox/Runtime/common/string/utf-16.cpp91223
    /branches/andy/draganddrop/src/VBox/Runtime/common/string/utf-16.cpp90781-91268
    /branches/andy/guestctrl20/src/VBox/Runtime/common/string/utf-16.cpp78916,​78930
    /branches/bird/hardenedwindows/src/VBox/Runtime/common/string/utf-16-case.cpp92961-94610
    /branches/dsen/gui/src/VBox/Runtime/common/string/utf-16.cpp79076-79078,​79089,​79109-79110,​79112-79113,​79127-79130,​79134,​79141,​79151,​79155,​79157-79159,​79193,​79197
    /branches/dsen/gui2/src/VBox/Runtime/common/string/utf-16.cpp79224,​79228,​79233,​79235,​79258,​79262-79263,​79273,​79341,​79345,​79354,​79357,​79387-79388,​79559-79569,​79572-79573,​79578,​79581-79582,​79590-79591,​79598-79599,​79602-79603,​79605-79606,​79632,​79635,​79637,​79644
    /branches/dsen/gui3/src/VBox/Runtime/common/string/utf-16.cpp79645-79692
File size: 6.6 KB
Line 
1/* $Id: utf-16-case.cpp 60481 2016-04-13 20:14:41Z vboxsync $ */
2/** @file
3 * IPRT - UTF-16, Case Sensitivity.
4 */
5
6/*
7 * Copyright (C) 2006-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/string.h>
32#include "internal/iprt.h"
33
34#include <iprt/uni.h>
35#include <iprt/alloc.h>
36#include <iprt/assert.h>
37#include <iprt/err.h>
38#include "internal/string.h"
39
40
41RTDECL(int) RTUtf16ICmp(register PCRTUTF16 pwsz1, register PCRTUTF16 pwsz2)
42{
43 if (pwsz1 == pwsz2)
44 return 0;
45 if (!pwsz1)
46 return -1;
47 if (!pwsz2)
48 return 1;
49
50 PCRTUTF16 pwsz1Start = pwsz1; /* keep it around in case we have to backtrack on a surrogate pair */
51 for (;;)
52 {
53 register RTUTF16 wc1 = *pwsz1;
54 register RTUTF16 wc2 = *pwsz2;
55 register int iDiff = wc1 - wc2;
56 if (iDiff)
57 {
58 /* unless they are *both* surrogate pairs, there is no chance they'll be identical. */
59 if ( wc1 < 0xd800
60 || wc2 < 0xd800
61 || wc1 > 0xdfff
62 || wc2 > 0xdfff)
63 {
64 /* simple UCS-2 char */
65 iDiff = RTUniCpToUpper(wc1) - RTUniCpToUpper(wc2);
66 if (iDiff)
67 iDiff = RTUniCpToLower(wc1) - RTUniCpToLower(wc2);
68 }
69 else
70 {
71 /* a damned pair */
72 RTUNICP uc1;
73 RTUNICP uc2;
74 if (wc1 >= 0xdc00)
75 {
76 if (pwsz1Start == pwsz1)
77 return iDiff;
78 uc1 = pwsz1[-1];
79 if (uc1 < 0xd800 || uc1 >= 0xdc00)
80 return iDiff;
81 uc1 = 0x10000 + (((uc1 & 0x3ff) << 10) | (wc1 & 0x3ff));
82 uc2 = 0x10000 + (((pwsz2[-1] & 0x3ff) << 10) | (wc2 & 0x3ff));
83 }
84 else
85 {
86 uc1 = *++pwsz1;
87 if (uc1 < 0xdc00 || uc1 >= 0xe000)
88 return iDiff;
89 uc1 = 0x10000 + (((wc1 & 0x3ff) << 10) | (uc1 & 0x3ff));
90 uc2 = 0x10000 + (((wc2 & 0x3ff) << 10) | (*++pwsz2 & 0x3ff));
91 }
92 iDiff = RTUniCpToUpper(uc1) - RTUniCpToUpper(uc2);
93 if (iDiff)
94 iDiff = RTUniCpToLower(uc1) - RTUniCpToLower(uc2); /* serious paranoia! */
95 }
96 if (iDiff)
97 return iDiff;
98 }
99 if (!wc1)
100 return 0;
101 pwsz1++;
102 pwsz2++;
103 }
104}
105RT_EXPORT_SYMBOL(RTUtf16ICmp);
106
107
108RTDECL(int) RTUtf16ICmpUtf8(PCRTUTF16 pwsz1, const char *psz2)
109{
110 /*
111 * NULL and empty strings are all the same.
112 */
113 if (!pwsz1)
114 return !psz2 || !*psz2 ? 0 : -1;
115 if (!psz2)
116 return !*pwsz1 ? 0 : 1;
117
118 /*
119 * Compare with a UTF-8 string by enumerating them char by char.
120 */
121 for (;;)
122 {
123 RTUNICP uc1;
124 int rc = RTUtf16GetCpEx(&pwsz1, &uc1);
125 AssertRCReturn(rc, 1);
126
127 RTUNICP uc2;
128 rc = RTStrGetCpEx(&psz2, &uc2);
129 AssertRCReturn(rc, -1);
130 if (uc1 == uc2)
131 {
132 if (uc1)
133 continue;
134 return 0;
135 }
136
137 if (RTUniCpToUpper(uc1) == RTUniCpToUpper(uc2))
138 continue;
139 if (RTUniCpToLower(uc1) == RTUniCpToLower(uc2))
140 continue;
141 return uc1 < uc2 ? -1 : 1;
142 }
143}
144RT_EXPORT_SYMBOL(RTUtf16CmpIUtf8);
145
146
147RTDECL(PRTUTF16) RTUtf16ToLower(PRTUTF16 pwsz)
148{
149 PRTUTF16 pwc = pwsz;
150 for (;;)
151 {
152 RTUTF16 wc = *pwc;
153 if (!wc)
154 break;
155 if (wc < 0xd800 || wc >= 0xdc00)
156 {
157 RTUNICP ucFolded = RTUniCpToLower(wc);
158 if (ucFolded < 0x10000)
159 *pwc++ = RTUniCpToLower(wc);
160 }
161 else
162 {
163 /* surrogate */
164 RTUTF16 wc2 = pwc[1];
165 if (wc2 >= 0xdc00 && wc2 <= 0xdfff)
166 {
167 RTUNICP uc = 0x10000 + (((wc & 0x3ff) << 10) | (wc2 & 0x3ff));
168 RTUNICP ucFolded = RTUniCpToLower(uc);
169 if (uc != ucFolded && ucFolded >= 0x10000) /* we don't support shrinking the string */
170 {
171 uc -= 0x10000;
172 *pwc++ = 0xd800 | (uc >> 10);
173 *pwc++ = 0xdc00 | (uc & 0x3ff);
174 }
175 }
176 else /* invalid encoding. */
177 pwc++;
178 }
179 }
180 return pwsz;
181}
182RT_EXPORT_SYMBOL(RTUtf16ToLower);
183
184
185RTDECL(PRTUTF16) RTUtf16ToUpper(PRTUTF16 pwsz)
186{
187 PRTUTF16 pwc = pwsz;
188 for (;;)
189 {
190 RTUTF16 wc = *pwc;
191 if (!wc)
192 break;
193 if (wc < 0xd800 || wc >= 0xdc00)
194 *pwc++ = RTUniCpToUpper(wc);
195 else
196 {
197 /* surrogate */
198 RTUTF16 wc2 = pwc[1];
199 if (wc2 >= 0xdc00 && wc2 <= 0xdfff)
200 {
201 RTUNICP uc = 0x10000 + (((wc & 0x3ff) << 10) | (wc2 & 0x3ff));
202 RTUNICP ucFolded = RTUniCpToUpper(uc);
203 if (uc != ucFolded && ucFolded >= 0x10000) /* we don't support shrinking the string */
204 {
205 uc -= 0x10000;
206 *pwc++ = 0xd800 | (uc >> 10);
207 *pwc++ = 0xdc00 | (uc & 0x3ff);
208 }
209 }
210 else /* invalid encoding. */
211 pwc++;
212 }
213 }
214 return pwsz;
215}
216RT_EXPORT_SYMBOL(RTUtf16ToUpper);
217
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette