| 2681 | |
| 2682 | |
| 2683 | static void move_to_string(thread_db* tdbb, dsc* fromDesc, dsc* toDesc) |
| 2684 | { |
| 2685 | /************************************** |
| 2686 | * |
| 2687 | * m o v e _ t o _ s t r i n g |
| 2688 | * |
| 2689 | ************************************** |
| 2690 | * |
| 2691 | * Functional description |
| 2692 | * Perform an assignment from a blob to another datatype. |
| 2693 | * |
| 2694 | **************************************/ |
| 2695 | SET_TDBB(tdbb); |
| 2696 | |
| 2697 | fb_assert(DTYPE_IS_BLOB_OR_QUAD(fromDesc->dsc_dtype)); |
| 2698 | fb_assert(!DTYPE_IS_BLOB_OR_QUAD(toDesc->dsc_dtype)); |
| 2699 | |
| 2700 | dsc blobAsText; |
| 2701 | blobAsText.dsc_dtype = dtype_text; |
| 2702 | |
| 2703 | if (DTYPE_IS_TEXT(toDesc->dsc_dtype)) |
| 2704 | blobAsText.dsc_ttype() = toDesc->dsc_ttype(); |
| 2705 | else |
| 2706 | blobAsText.dsc_ttype() = ttype_ascii; |
| 2707 | |
| 2708 | Request* request = tdbb->getRequest(); |
| 2709 | jrd_tra* transaction = request ? request->req_transaction : tdbb->getTransaction(); |
| 2710 | transaction = transaction->getOuter(); |
| 2711 | |
| 2712 | UCharBuffer bpb; |
| 2713 | BLB_gen_bpb_from_descs(fromDesc, &blobAsText, bpb); |
| 2714 | |
| 2715 | blb* blob = blb::open2(tdbb, transaction, |
| 2716 | (bid*) fromDesc->dsc_address, bpb.getCount(), bpb.begin()); |
| 2717 | |
| 2718 | const CharSet* fromCharSet = INTL_charset_lookup(tdbb, fromDesc->dsc_scale); |
| 2719 | const CharSet* toCharSet = INTL_charset_lookup(tdbb, INTL_GET_CHARSET(&blobAsText)); |
| 2720 | |
| 2721 | HalfStaticArray<UCHAR, BUFFER_SMALL> buffer; |
| 2722 | buffer.getBuffer((blob->blb_length / fromCharSet->minBytesPerChar()) * toCharSet->maxBytesPerChar()); |
| 2723 | const ULONG len = blob->BLB_get_data(tdbb, buffer.begin(), buffer.getCapacity(), true); |
| 2724 | |
| 2725 | if (len > MAX_STR_SIZE) |
| 2726 | ERR_post(Arg::Gds(isc_arith_except) << Arg::Gds(isc_blob_truncation)); |
| 2727 | |
| 2728 | blobAsText.dsc_address = buffer.begin(); |
| 2729 | blobAsText.dsc_length = (USHORT) len; |
| 2730 | |
| 2731 | MOV_move(tdbb, &blobAsText, toDesc); |
| 2732 | } |
| 2733 | |
| 2734 | |
| 2735 | // Release a blob and associated blocks. Among other things, disconnect it from the transaction. |
no test coverage detected