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