1 /** 2 * Part of the D programming language runtime library. 3 */ 4 5 /* 6 * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com 7 * Written by Walter Bright 8 * 9 * This software is provided 'as-is', without any express or implied 10 * warranty. In no event will the authors be held liable for any damages 11 * arising from the use of this software. 12 * 13 * Permission is granted to anyone to use this software for any purpose, 14 * including commercial applications, and to alter it and redistribute it 15 * freely, in both source and binary form, subject to the following 16 * restrictions: 17 * 18 * o The origin of this software must not be misrepresented; you must not 19 * claim that you wrote the original software. If you use this software 20 * in a product, an acknowledgment in the product documentation would be 21 * appreciated but is not required. 22 * o Altered source versions must be plainly marked as such, and must not 23 * be misrepresented as being the original software. 24 * o This notice may not be removed or altered from any source 25 * distribution. 26 */ 27 28 module rt.compiler.gdc.rt.aApply; 29 30 /* 31 * Modified by Sean Kelly <sean@f4.ca> for use with Tango. 32 */ 33 34 /* This code handles decoding UTF strings for foreach loops. 35 * There are 6 combinations of conversions between char, wchar, 36 * and dchar, and 2 of each of those. 37 */ 38 39 private import rt.compiler.util.utf; 40 41 /********************************************** 42 */ 43 44 // dg is D, but _aApplycd() is C 45 extern (D) typedef int delegate(void *) dg_t; 46 47 extern (C) int _aApplycd1(char[] aa, dg_t dg) 48 { int result; 49 size_t i; 50 size_t len = aa.length; 51 52 debug(apply) printf("_aApplycd1(), len = %d\n", len); 53 for (i = 0; i < len; ) 54 { dchar d; 55 56 d = aa[i]; 57 if (d & 0x80) 58 d = decode(aa, i); 59 else 60 i++; 61 result = dg(cast(void *)&d); 62 if (result) 63 break; 64 } 65 return result; 66 } 67 68 extern (C) int _aApplywd1(wchar[] aa, dg_t dg) 69 { int result; 70 size_t i; 71 size_t len = aa.length; 72 73 debug(apply) printf("_aApplywd1(), len = %d\n", len); 74 for (i = 0; i < len; ) 75 { dchar d; 76 77 d = aa[i]; 78 if (d & ~0x7F) 79 d = decode(aa, i); 80 else 81 i++; 82 result = dg(cast(void *)&d); 83 if (result) 84 break; 85 } 86 return result; 87 } 88 89 extern (C) int _aApplycw1(char[] aa, dg_t dg) 90 { int result; 91 size_t i; 92 size_t len = aa.length; 93 94 debug(apply) printf("_aApplycw1(), len = %d\n", len); 95 for (i = 0; i < len; ) 96 { dchar d; 97 wchar w; 98 99 w = aa[i]; 100 if (w & 0x80) 101 { d = decode(aa, i); 102 if (d <= 0xFFFF) 103 w = cast(wchar) d; 104 else 105 { 106 w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800); 107 result = dg(cast(void *)&w); 108 if (result) 109 break; 110 w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00); 111 } 112 } 113 else 114 i++; 115 result = dg(cast(void *)&w); 116 if (result) 117 break; 118 } 119 return result; 120 } 121 122 extern (C) int _aApplywc1(wchar[] aa, dg_t dg) 123 { int result; 124 size_t i; 125 size_t len = aa.length; 126 127 debug(apply) printf("_aApplywc1(), len = %d\n", len); 128 for (i = 0; i < len; ) 129 { dchar d; 130 wchar w; 131 char c; 132 133 w = aa[i]; 134 if (w & ~0x7F) 135 { 136 char[4] buf; 137 138 d = decode(aa, i); 139 auto b = toUTF8(buf, d); 140 foreach (char c2; b) 141 { 142 result = dg(cast(void *)&c2); 143 if (result) 144 return result; 145 } 146 continue; 147 } 148 else 149 { c = cast(char)w; 150 i++; 151 } 152 result = dg(cast(void *)&c); 153 if (result) 154 break; 155 } 156 return result; 157 } 158 159 extern (C) int _aApplydc1(dchar[] aa, dg_t dg) 160 { int result; 161 162 debug(apply) printf("_aApplydc1(), len = %d\n", aa.length); 163 foreach (dchar d; aa) 164 { 165 char c; 166 167 if (d & ~0x7F) 168 { 169 char[4] buf; 170 171 auto b = toUTF8(buf, d); 172 foreach (char c2; b) 173 { 174 result = dg(cast(void *)&c2); 175 if (result) 176 return result; 177 } 178 continue; 179 } 180 else 181 { 182 c = cast(char)d; 183 } 184 result = dg(cast(void *)&c); 185 if (result) 186 break; 187 } 188 return result; 189 } 190 191 extern (C) int _aApplydw1(dchar[] aa, dg_t dg) 192 { int result; 193 194 debug(apply) printf("_aApplydw1(), len = %d\n", aa.length); 195 foreach (dchar d; aa) 196 { 197 wchar w; 198 199 if (d <= 0xFFFF) 200 w = cast(wchar) d; 201 else 202 { 203 w = cast(wchar)((((d - 0x10000) >> 10) & 0x3FF) + 0xD800); 204 result = dg(cast(void *)&w); 205 if (result) 206 break; 207 w = cast(wchar)(((d - 0x10000) & 0x3FF) + 0xDC00); 208 } 209 result = dg(cast(void *)&w); 210 if (result) 211 break; 212 } 213 return result; 214 } 215 216 217 /****************************************************************************/ 218 219 // dg is D, but _aApplycd2() is C 220 extern (D) typedef int delegate(void *, void *) dg2_t; 221 222 extern (C) int _aApplycd2(char[] aa, dg2_t dg) 223 { int result; 224 size_t i; 225 size_t n; 226 size_t len = aa.length; 227 228 debug(apply) printf("_aApplycd2(), len = %d\n", len); 229 for (i = 0; i < len; i += n) 230 { dchar d; 231 232 d = aa[i]; 233 if (d & 0x80) 234 { 235 n = i; 236 d = decode(aa, n); 237 n -= i; 238 } 239 else 240 n = 1; 241 result = dg(&i, cast(void *)&d); 242 if (result) 243 break; 244 } 245 return result; 246 } 247 248 extern (C) int _aApplywd2(wchar[] aa, dg2_t dg) 249 { int result; 250 size_t i; 251 size_t n; 252 size_t len = aa.length; 253 254 debug(apply) printf("_aApplywd2(), len = %d\n", len); 255 for (i = 0; i < len; i += n) 256 { dchar d; 257 258 d = aa[i]; 259 if (d & ~0x7F) 260 { 261 n = i; 262 d = decode(aa, n); 263 n -= i; 264 } 265 else 266 n = 1; 267 result = dg(&i, cast(void *)&d); 268 if (result) 269 break; 270 } 271 return result; 272 } 273 274 extern (C) int _aApplycw2(char[] aa, dg2_t dg) 275 { int result; 276 size_t i; 277 size_t n; 278 size_t len = aa.length; 279 280 debug(apply) printf("_aApplycw2(), len = %d\n", len); 281 for (i = 0; i < len; i += n) 282 { dchar d; 283 wchar w; 284 285 w = aa[i]; 286 if (w & 0x80) 287 { n = i; 288 d = decode(aa, n); 289 n -= i; 290 if (d <= 0xFFFF) 291 w = cast(wchar) d; 292 else 293 { 294 w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800); 295 result = dg(&i, cast(void *)&w); 296 if (result) 297 break; 298 w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00); 299 } 300 } 301 else 302 n = 1; 303 result = dg(&i, cast(void *)&w); 304 if (result) 305 break; 306 } 307 return result; 308 } 309 310 extern (C) int _aApplywc2(wchar[] aa, dg2_t dg) 311 { int result; 312 size_t i; 313 size_t n; 314 size_t len = aa.length; 315 316 debug(apply) printf("_aApplywc2(), len = %d\n", len); 317 for (i = 0; i < len; i += n) 318 { dchar d; 319 wchar w; 320 char c; 321 322 w = aa[i]; 323 if (w & ~0x7F) 324 { 325 char[4] buf; 326 327 n = i; 328 d = decode(aa, n); 329 n -= i; 330 auto b = toUTF8(buf, d); 331 foreach (char c2; b) 332 { 333 result = dg(&i, cast(void *)&c2); 334 if (result) 335 return result; 336 } 337 continue; 338 } 339 else 340 { c = cast(char)w; 341 n = 1; 342 } 343 result = dg(&i, cast(void *)&c); 344 if (result) 345 break; 346 } 347 return result; 348 } 349 350 extern (C) int _aApplydc2(dchar[] aa, dg2_t dg) 351 { int result; 352 size_t i; 353 size_t len = aa.length; 354 355 debug(apply) printf("_aApplydc2(), len = %d\n", len); 356 for (i = 0; i < len; i++) 357 { dchar d; 358 char c; 359 360 d = aa[i]; 361 if (d & ~0x7F) 362 { 363 char[4] buf; 364 365 auto b = toUTF8(buf, d); 366 foreach (char c2; b) 367 { 368 result = dg(&i, cast(void *)&c2); 369 if (result) 370 return result; 371 } 372 continue; 373 } 374 else 375 { c = cast(char)d; 376 } 377 result = dg(&i, cast(void *)&c); 378 if (result) 379 break; 380 } 381 return result; 382 } 383 384 extern (C) int _aApplydw2(dchar[] aa, dg2_t dg) 385 { int result; 386 387 debug(apply) printf("_aApplydw2(), len = %d\n", aa.length); 388 foreach (size_t i, dchar d; aa) 389 { 390 wchar w; 391 auto j = i; 392 393 if (d <= 0xFFFF) 394 w = cast(wchar) d; 395 else 396 { 397 w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800); 398 result = dg(&j, cast(void *)&w); 399 if (result) 400 break; 401 w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00); 402 } 403 result = dg(&j, cast(void *)&w); 404 if (result) 405 break; 406 } 407 return result; 408 }