| 3666 | } |
| 3667 | |
| 3668 | dsc* evlEncodeDecodeHex(thread_db* tdbb, bool encodeFlag, const SysFunction* function, const NestValueArray& args, impure_value* impure) |
| 3669 | { |
| 3670 | const dsc* arg = EVL_expr(tdbb, tdbb->getRequest(), args[0]); |
| 3671 | if (!arg) // return NULL if value is NULL |
| 3672 | return NULL; |
| 3673 | |
| 3674 | const unsigned BLOB_BUF = 4096; |
| 3675 | UCHAR in[BLOB_BUF]; |
| 3676 | const UCHAR* ptr; |
| 3677 | unsigned len = 0; |
| 3678 | HalfStaticArray<UCHAR, BLOB_BUF> out; |
| 3679 | UCHAR last; |
| 3680 | unsigned pos = 0; |
| 3681 | AutoPtr<blb> inBlob, outBlob; |
| 3682 | |
| 3683 | if (arg->isBlob()) |
| 3684 | { |
| 3685 | // open all blobs as stream - that's perfectly OK for newly created blob with hex ascii |
| 3686 | // and enables exact restore of binary blob up to segmented structure if present |
| 3687 | inBlob.reset(blb::open2(tdbb, tdbb->getRequest()->req_transaction, |
| 3688 | reinterpret_cast<const bid*>(arg->dsc_address), sizeof(streamBpb), streamBpb)); |
| 3689 | outBlob.reset(blb::create2(tdbb, tdbb->getRequest()->req_transaction, |
| 3690 | &impure->vlu_misc.vlu_bid, sizeof(streamBpb), streamBpb)); |
| 3691 | } |
| 3692 | else |
| 3693 | ptr = CVT_get_bytes(arg, len); |
| 3694 | |
| 3695 | for(;; --len, ++pos) |
| 3696 | { |
| 3697 | if (arg->isBlob() && !len) |
| 3698 | { |
| 3699 | // try to get next portion of data from the blob |
| 3700 | len = inBlob->BLB_get_data(tdbb, in, sizeof in, false); |
| 3701 | ptr = in; |
| 3702 | } |
| 3703 | if (!len) |
| 3704 | break; |
| 3705 | |
| 3706 | UCHAR c = *ptr++; |
| 3707 | if (encodeFlag) |
| 3708 | { |
| 3709 | out.add(hexChar(c >> 4)); |
| 3710 | out.add(hexChar(c)); |
| 3711 | } |
| 3712 | else |
| 3713 | { |
| 3714 | if (pos & 1) |
| 3715 | out.add((last << 4) + binChar(c, pos)); |
| 3716 | else |
| 3717 | last = binChar(c, pos); |
| 3718 | } |
| 3719 | |
| 3720 | if (out.getCount() >= BLOB_BUF && arg->isBlob()) |
| 3721 | { |
| 3722 | outBlob->BLB_put_data(tdbb, out.begin(), out.getCount()); |
| 3723 | out.clear(); |
| 3724 | } |
| 3725 | } |
no test coverage detected