| 487 | |
| 488 | template <typename T> |
| 489 | static void getMultiPartConnectParameter(T& putTo, ClumpletReader& id, UCHAR param) |
| 490 | { |
| 491 | // This array is needed only to make sure that all parts of specific data are present |
| 492 | UCHAR checkBytes[256]; |
| 493 | memset(checkBytes, 0, sizeof(checkBytes)); |
| 494 | UCHAR top = 0; |
| 495 | |
| 496 | for (id.rewind(); !id.isEof(); id.moveNext()) |
| 497 | { |
| 498 | if (id.getClumpTag() == param) |
| 499 | { |
| 500 | const UCHAR* specData = id.getBytes(); |
| 501 | FB_SIZE_T len = id.getClumpLength(); |
| 502 | fb_assert(len <= 255); |
| 503 | |
| 504 | if (len > 1) |
| 505 | { |
| 506 | --len; |
| 507 | unsigned offset = specData[0]; |
| 508 | if (offset + 1 > top) |
| 509 | top = offset + 1; |
| 510 | if (checkBytes[offset]) |
| 511 | { |
| 512 | (Arg::Gds(isc_multi_segment_dup) << Arg::Num(offset)).raise(); |
| 513 | } |
| 514 | checkBytes[offset] = 1; |
| 515 | |
| 516 | offset *= SEGMENT_DATA_SIZE; |
| 517 | ++specData; |
| 518 | if (offset + len > putTo.getCount()) |
| 519 | putTo.grow(offset + len); |
| 520 | memcpy(&putTo[offset], specData, len); |
| 521 | } |
| 522 | } |
| 523 | } |
| 524 | |
| 525 | for (UCHAR segment = 0; segment < top; ++segment) |
| 526 | { |
| 527 | if (!checkBytes[segment]) |
| 528 | (Arg::Gds(isc_multi_segment) << Arg::Num(segment)).raise(); |
| 529 | } |
| 530 | |
| 531 | HANDSHAKE_DEBUG(fprintf(stderr, "Srv: getMultiPartConnectParameter: loaded tag %d length %u\n", |
| 532 | param, static_cast<unsigned>(putTo.getCount()))); |
| 533 | } |
| 534 | |
| 535 | |
| 536 | // delayed authentication block for auth callback |