Bug 448909 - Need more controls WHATWG Video tag (followup patch). r=mconnor
[wine-gecko.git] / intl / uconv / ucvlatin / nsUnicodeToUTF32.cpp
blob10de40dc268bb96c67d8198279bc45e94b9df9e3
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
3 */
4 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
17 * The Original Code is Mozilla Communicator client code.
19 * The Initial Developer of the Original Code is
20 * Netscape Communications Corporation.
21 * Portions created by the Initial Developer are Copyright (C) 1998
22 * the Initial Developer. All Rights Reserved.
24 * Contributor(s):
25 * Jungshik Shin <jshin@mailaps.org>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #include <string.h>
42 #include "nsUCSupport.h"
43 #include "nsUnicodeToUTF32.h"
45 #ifdef IS_BIG_ENDIAN
46 #define UCS4_TO_LE_STRING(u, s) \
47 PR_BEGIN_MACRO \
48 s[3] = PRUint8(((u) >> 24) & 0xffL); \
49 s[2] = PRUint8(((u) >> 16) & 0xffL); \
50 s[1] = PRUint8(((u) >> 8) & 0xffL); \
51 s[0] = PRUint8((u) & 0xffL); \
52 PR_END_MACRO
53 #else
54 #define UCS4_TO_LE_STRING(u, s) \
55 PR_BEGIN_MACRO \
56 *((PRUint32*)(s)) = (u); \
57 PR_END_MACRO
58 #endif
60 #ifdef IS_BIG_ENDIAN
61 #define UCS4_TO_BE_STRING(u, s) \
62 PR_BEGIN_MACRO \
63 *((PRUint32*)(s)) = (u); \
64 PR_END_MACRO
65 #else
66 #define UCS4_TO_BE_STRING(u, s) \
67 PR_BEGIN_MACRO \
68 s[0] = PRUint8(((u) >> 24) & 0xffL); \
69 s[1] = PRUint8(((u) >> 16) & 0xffL); \
70 s[2] = PRUint8(((u) >> 8) & 0xffL); \
71 s[3] = PRUint8((u) & 0xffL); \
72 PR_END_MACRO
73 #endif
75 //----------------------------------------------------------------------
76 // Static functions common to nsUnicodeToUTF32LE and nsUnicodeToUTF32BE
78 static nsresult ConvertCommon(const PRUnichar * aSrc,
79 PRInt32 * aSrcLength,
80 char * aDest,
81 PRInt32 * aDestLength,
82 PRUnichar * aHighSurrogate,
83 PRBool aIsLE)
85 const PRUnichar * src = aSrc;
86 const PRUnichar * srcEnd = aSrc + *aSrcLength;
87 char * dest = aDest;
88 const char * destEnd = aDest + *aDestLength;
89 PRUint32 ucs4;
92 // left-over high surroage code point from the prev. run.
93 if (*aHighSurrogate)
95 if (! *aSrcLength)
97 *aDestLength = 0;
98 return NS_OK_UENC_MOREINPUT;
100 if (*aDestLength < 4)
102 *aSrcLength = 0;
103 *aDestLength = 0;
104 return NS_OK_UENC_MOREOUTPUT;
106 if ((*src & 0xfc00) != 0xdc00) // Not a low surrogate codepoint. Unpaird.
107 ucs4 = PRUint32(*aHighSurrogate);
108 else
109 ucs4 = (((*aHighSurrogate & 0x3ffL) << 10) | (*src & 0x3ffL)) + 0x10000;
111 ++src;
112 if (aIsLE)
113 UCS4_TO_LE_STRING(ucs4, dest);
114 else
115 UCS4_TO_BE_STRING(ucs4, dest);
116 dest += 4;
117 *aHighSurrogate = 0;
120 while (src < srcEnd) {
121 // regular codepoint or an unpaired low surrogate
122 if ((src[0] & 0xfc00) != 0xd800)
124 if (destEnd - dest < 4)
125 goto error_more_output;
126 ucs4 = PRUint32(src[0]);
128 else // high surrogate
130 if ((src+1) >= srcEnd) {
131 //we need another surrogate to complete this unicode char
132 *aHighSurrogate = src[0];
133 *aDestLength = dest - aDest;
134 return NS_OK_UENC_MOREINPUT;
136 //handle surrogate
137 if (destEnd - dest < 4)
138 goto error_more_output;
139 if ((src[1] & 0xfc00) != 0xdc00) // unpaired
140 ucs4 = PRUint32(src[0]);
141 else
142 { // convert surrogate pair to UCS4
143 ucs4 = (((src[0] & 0x3ffL) << 10) | (src[1] & 0x3ffL)) + 0x10000;
144 *aHighSurrogate = 0;
145 ++src;
148 if (aIsLE)
149 UCS4_TO_LE_STRING(ucs4, dest);
150 else
151 UCS4_TO_BE_STRING(ucs4, dest);
152 dest += 4;
153 ++src;
156 *aDestLength = dest - aDest;
157 return NS_OK;
159 error_more_output:
160 *aSrcLength = src - aSrc;
161 *aDestLength = dest - aDest;
162 return NS_OK_UENC_MOREOUTPUT;
166 static nsresult FinishCommon(char * aDest,
167 PRInt32 * aDestLength,
168 PRUnichar * aHighSurrogate,
169 PRBool aIsLE)
171 char * dest = aDest;
173 if (*aHighSurrogate) {
174 if (*aDestLength < 4) {
175 *aDestLength = 0;
176 return NS_OK_UENC_MOREOUTPUT;
178 PRUint32 high = PRUint32(*aHighSurrogate);
179 if (aIsLE)
180 UCS4_TO_LE_STRING(high, dest);
181 else
182 UCS4_TO_BE_STRING(high, dest);
183 *aHighSurrogate = 0;
184 *aDestLength = 4;
185 return NS_OK;
188 *aDestLength = 0;
189 return NS_OK;
194 //----------------------------------------------------------------------
195 // Class nsUnicodeToUTF32 [implementation]
197 NS_IMPL_ISUPPORTS1(nsUnicodeToUTF32, nsIUnicodeEncoder)
200 //----------------------------------------------------------------------
201 // Subclassing of nsIUnicodeEncoder class [implementation]
203 NS_IMETHODIMP nsUnicodeToUTF32::GetMaxLength(const PRUnichar * aSrc,
204 PRInt32 aSrcLength,
205 PRInt32 * aDestLength)
207 *aDestLength = aSrcLength * 4;
208 return NS_OK;
211 NS_IMETHODIMP nsUnicodeToUTF32::FillInfo(PRUint32 *aInfo)
213 memset(aInfo, 0xFF, (0x10000L >> 3));
214 return NS_OK;
218 //----------------------------------------------------------------------
219 // Class nsUnicodeToUTF32BE [implementation]
221 //----------------------------------------------------------------------
222 // Subclassing of nsUnicodeToUTF32 class [implementation]
225 NS_IMETHODIMP nsUnicodeToUTF32BE::Convert(const PRUnichar * aSrc,
226 PRInt32 * aSrcLength,
227 char * aDest,
228 PRInt32 * aDestLength)
230 return ConvertCommon(aSrc, aSrcLength, aDest, aDestLength,
231 &mHighSurrogate, PR_FALSE);
234 NS_IMETHODIMP nsUnicodeToUTF32BE::Finish(char * aDest,
235 PRInt32 * aDestLength)
237 return FinishCommon(aDest, aDestLength, &mHighSurrogate, PR_FALSE);
241 //----------------------------------------------------------------------
242 // Class nsUnicodeToUTF32LE [implementation]
244 //----------------------------------------------------------------------
245 // Subclassing of nsUnicodeToUTF32 class [implementation]
248 NS_IMETHODIMP nsUnicodeToUTF32LE::Convert(const PRUnichar * aSrc,
249 PRInt32 * aSrcLength,
250 char * aDest,
251 PRInt32 * aDestLength)
253 return ConvertCommon(aSrc, aSrcLength, aDest, aDestLength,
254 &mHighSurrogate, PR_TRUE);
257 NS_IMETHODIMP nsUnicodeToUTF32LE::Finish(char * aDest,
258 PRInt32 * aDestLength)
260 return FinishCommon(aDest, aDestLength, &mHighSurrogate, PR_TRUE);