| | 368 | /** |
|---|
| | 369 | * For non-zero initializers |
|---|
| | 370 | */ |
|---|
| | 371 | |
|---|
| | 372 | extern (C) |
|---|
| | 373 | byte[] _d_arraysetlength2(size_t newlength, size_t sizeelem, Array *p, ...) |
|---|
| | 374 | in |
|---|
| | 375 | { |
|---|
| | 376 | assert(sizeelem); |
|---|
| | 377 | assert(!p.length || p.data); |
|---|
| | 378 | } |
|---|
| | 379 | body |
|---|
| | 380 | { |
|---|
| | 381 | byte* newdata; |
|---|
| | 382 | |
|---|
| | 383 | debug |
|---|
| | 384 | { |
|---|
| | 385 | printf("_d_arraysetlength2(p = %p, sizeelem = %d, newlength = %d)\n", p, sizeelem, newlength); |
|---|
| | 386 | if (p) |
|---|
| | 387 | printf("\tp.data = %p, p.length = %d\n", p.data, p.length); |
|---|
| | 388 | } |
|---|
| | 389 | |
|---|
| | 390 | if (newlength) |
|---|
| | 391 | { |
|---|
| | 392 | version (D_InlineAsm_X86) |
|---|
| | 393 | { |
|---|
| | 394 | size_t newsize = void; |
|---|
| | 395 | |
|---|
| | 396 | asm |
|---|
| | 397 | { |
|---|
| | 398 | mov EAX,newlength ; |
|---|
| | 399 | mul EAX,sizeelem ; |
|---|
| | 400 | mov newsize,EAX ; |
|---|
| | 401 | jc Loverflow ; |
|---|
| | 402 | } |
|---|
| | 403 | } |
|---|
| | 404 | else |
|---|
| | 405 | { |
|---|
| | 406 | size_t newsize = sizeelem * newlength; |
|---|
| | 407 | |
|---|
| | 408 | if (newsize / newlength != sizeelem) |
|---|
| | 409 | goto Loverflow; |
|---|
| | 410 | } |
|---|
| | 411 | //printf("newsize = %x, newlength = %x\n", newsize, newlength); |
|---|
| | 412 | |
|---|
| | 413 | size_t size = p.length * sizeelem; |
|---|
| | 414 | |
|---|
| | 415 | if (p.length) |
|---|
| | 416 | { |
|---|
| | 417 | newdata = p.data; |
|---|
| | 418 | if (newlength > p.length) |
|---|
| | 419 | { |
|---|
| | 420 | size_t cap = gc_sizeOf(p.data); |
|---|
| | 421 | |
|---|
| | 422 | if (cap <= newsize) |
|---|
| | 423 | { |
|---|
| | 424 | newdata = cast(byte *)gc_malloc(newsize + 1); |
|---|
| | 425 | newdata[0 .. size] = p.data[0 .. size]; |
|---|
| | 426 | } |
|---|
| | 427 | newdata[size .. newsize] = 0; |
|---|
| | 428 | } |
|---|
| | 429 | } |
|---|
| | 430 | else |
|---|
| | 431 | { |
|---|
| | 432 | newdata = cast(byte *)gc_malloc(newsize + 1); |
|---|
| | 433 | } |
|---|
| | 434 | |
|---|
| | 435 | va_list q; |
|---|
| | 436 | va_start!(Array *)(q, p); // q is pointer to initializer |
|---|
| | 437 | |
|---|
| | 438 | if (newsize > size) |
|---|
| | 439 | { |
|---|
| | 440 | if (sizeelem == 1) |
|---|
| | 441 | newdata[size .. newsize] = *(cast(byte*)q); |
|---|
| | 442 | else |
|---|
| | 443 | { |
|---|
| | 444 | for (size_t u = size; u < newsize; u += sizeelem) |
|---|
| | 445 | { |
|---|
| | 446 | memcpy(newdata + u, q, sizeelem); |
|---|
| | 447 | } |
|---|
| | 448 | } |
|---|
| | 449 | } |
|---|
| | 450 | } |
|---|
| | 451 | else |
|---|
| | 452 | { |
|---|
| | 453 | newdata = null; |
|---|
| | 454 | } |
|---|
| | 455 | |
|---|
| | 456 | p.data = newdata; |
|---|
| | 457 | p.length = newlength; |
|---|
| | 458 | return newdata[0 .. newlength]; |
|---|
| | 459 | |
|---|
| | 460 | Loverflow: |
|---|
| | 461 | onOutOfMemoryError(); |
|---|
| | 462 | } |
|---|
| | 463 | |
|---|