Bug 601299: Find RegExpStatics in cx->globalObject if necessary. (r=mrbkap)
[mozilla-central.git] / netwerk / dns / race.c
bloba7973d7af751acc8e7213546b220700c264af44b
1 /*
2 * Copyright (c) 2000,2001,2002 Japan Network Information Center.
3 * All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set forth bellow.
6 *
7 * LICENSE TERMS AND CONDITIONS
8 *
9 * The following License Terms and Conditions apply, unless a different
10 * license is obtained from Japan Network Information Center ("JPNIC"),
11 * a Japanese association, Kokusai-Kougyou-Kanda Bldg 6F, 2-3-4 Uchi-Kanda,
12 * Chiyoda-ku, Tokyo 101-0047, Japan.
14 * 1. Use, Modification and Redistribution (including distribution of any
15 * modified or derived work) in source and/or binary forms is permitted
16 * under this License Terms and Conditions.
18 * 2. Redistribution of source code must retain the copyright notices as they
19 * appear in each source code file, this License Terms and Conditions.
21 * 3. Redistribution in binary form must reproduce the Copyright Notice,
22 * this License Terms and Conditions, in the documentation and/or other
23 * materials provided with the distribution. For the purposes of binary
24 * distribution the "Copyright Notice" refers to the following language:
25 * "Copyright (c) 2000-2002 Japan Network Information Center. All rights reserved."
27 * 4. The name of JPNIC may not be used to endorse or promote products
28 * derived from this Software without specific prior written approval of
29 * JPNIC.
31 * 5. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY JPNIC
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
34 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JPNIC BE LIABLE
35 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
38 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
39 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
40 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
45 #include <stddef.h>
46 #include <stdlib.h>
47 #include <string.h>
49 #include "nsIDNKitInterface.h"
52 #define RACE_2OCTET_MODE 0xd8
53 #define RACE_ESCAPE 0xff
54 #define RACE_ESCAPE_2ND 0x99
57 * Compression type.
59 enum {
60 compress_one, /* all characters are in a single row */
61 compress_two, /* row 0 and another row */
62 compress_none /* nope */
66 idn_result_t
67 race_decode_decompress(const char *from, PRUint16 *buf, size_t buflen)
69 PRUint16 *p = buf;
70 unsigned int bitbuf = 0;
71 int bitlen = 0;
72 unsigned int i, j;
73 size_t len;
75 while (*from != '\0') {
76 int c = *from++;
77 int x;
79 if ('a' <= c && c <= 'z')
80 x = c - 'a';
81 else if ('A' <= c && c <= 'Z')
82 x = c - 'A';
83 else if ('2' <= c && c <= '7')
84 x = c - '2' + 26;
85 else
86 return (idn_invalid_encoding);
88 bitbuf = (bitbuf << 5) + x;
89 bitlen += 5;
90 if (bitlen >= 8) {
91 *p++ = (bitbuf >> (bitlen - 8)) & 0xff;
92 bitlen -= 8;
95 len = p - buf;
98 * Now 'buf' holds the decoded string.
102 * Decompress.
104 if (buf[0] == RACE_2OCTET_MODE) {
105 if ((len - 1) % 2 != 0)
106 return (idn_invalid_encoding);
107 for (i = 1, j = 0; i < len; i += 2, j++)
108 buf[j] = (buf[i] << 8) + buf[i + 1];
109 len = j;
110 } else {
111 PRUint16 c = buf[0] << 8; /* higher octet */
113 for (i = 1, j = 0; i < len; j++) {
114 if (buf[i] == RACE_ESCAPE) {
115 if (i + 1 >= len)
116 return (idn_invalid_encoding);
117 else if (buf[i + 1] == RACE_ESCAPE_2ND)
118 buf[j] = c | 0xff;
119 else
120 buf[j] = buf[i + 1];
121 i += 2;
123 } else if (buf[i] == 0x99 && c == 0x00) {
125 * The RACE specification says this is error.
127 return (idn_invalid_encoding);
129 } else {
130 buf[j] = c | buf[i++];
133 len = j;
135 buf[len] = '\0';
137 return (idn_success);
140 idn_result_t
141 race_compress_encode(const PRUint16 *p, int compress_mode,
142 char *to, size_t tolen)
144 PRUint32 bitbuf = *p++; /* bit stream buffer */
145 int bitlen = 8; /* # of bits in 'bitbuf' */
147 while (*p != '\0' || bitlen > 0) {
148 unsigned int c = *p;
150 if (c == '\0') {
151 /* End of data. Flush. */
152 bitbuf <<= (5 - bitlen);
153 bitlen = 5;
154 } else if (compress_mode == compress_none) {
155 /* Push 16 bit data. */
156 bitbuf = (bitbuf << 16) | c;
157 bitlen += 16;
158 p++;
159 } else {/* compress_mode == compress_one/compress_two */
160 /* Push 8 or 16 bit data. */
161 if (compress_mode == compress_two &&
162 (c & 0xff00) == 0) {
163 /* Upper octet is zero (and not U1). */
164 bitbuf = (bitbuf << 16) | 0xff00 | c;
165 bitlen += 16;
166 } else if ((c & 0xff) == 0xff) {
167 /* Lower octet is 0xff. */
168 bitbuf = (bitbuf << 16) |
169 (RACE_ESCAPE << 8) | RACE_ESCAPE_2ND;
170 bitlen += 16;
171 } else {
172 /* Just output lower octet. */
173 bitbuf = (bitbuf << 8) | (c & 0xff);
174 bitlen += 8;
176 p++;
180 * Output bits in 'bitbuf' in 5-bit unit.
182 while (bitlen >= 5) {
183 int x;
185 /* Get top 5 bits. */
186 x = (bitbuf >> (bitlen - 5)) & 0x1f;
187 bitlen -= 5;
189 /* Encode. */
190 if (x < 26)
191 x += 'a';
192 else
193 x = (x - 26) + '2';
195 if (tolen < 1)
196 return (idn_buffer_overflow);
198 *to++ = x;
199 tolen--;
203 if (tolen <= 0)
204 return (idn_buffer_overflow);
206 *to = '\0';
207 return (idn_success);
211 get_compress_mode(PRUint16 *p) {
212 int zero = 0;
213 unsigned int upper = 0;
214 PRUint16 *modepos = p - 1;
216 while (*p != '\0') {
217 unsigned int hi = *p++ & 0xff00;
219 if (hi == 0) {
220 zero++;
221 } else if (hi == upper) {
223 } else if (upper == 0) {
224 upper = hi;
225 } else {
226 *modepos = RACE_2OCTET_MODE;
227 return (compress_none);
230 *modepos = upper >> 8;
231 if (upper > 0 && zero > 0)
232 return (compress_two);
233 else
234 return (compress_one);