| 6379 | |
| 6380 | |
| 6381 | dsc* evlReverse(thread_db* tdbb, const SysFunction*, const NestValueArray& args, |
| 6382 | impure_value* impure) |
| 6383 | { |
| 6384 | fb_assert(args.getCount() == 1); |
| 6385 | |
| 6386 | Request* request = tdbb->getRequest(); |
| 6387 | |
| 6388 | dsc* value = EVL_expr(tdbb, request, args[0]); |
| 6389 | if (request->req_flags & req_null) // return NULL if value is NULL |
| 6390 | return NULL; |
| 6391 | |
| 6392 | CharSet* cs = INTL_charset_lookup(tdbb, value->getCharSet()); |
| 6393 | |
| 6394 | if (value->isBlob()) |
| 6395 | { |
| 6396 | blb* blob = blb::open(tdbb, tdbb->getRequest()->req_transaction, |
| 6397 | reinterpret_cast<bid*>(value->dsc_address)); |
| 6398 | |
| 6399 | HalfStaticArray<UCHAR, BUFFER_LARGE> buffer; |
| 6400 | HalfStaticArray<UCHAR, BUFFER_LARGE> buffer2; |
| 6401 | |
| 6402 | UCHAR* p = buffer.getBuffer(blob->blb_length); |
| 6403 | const SLONG len = blob->BLB_get_data(tdbb, p, blob->blb_length, true); |
| 6404 | |
| 6405 | if (cs->isMultiByte() || cs->minBytesPerChar() > 1) |
| 6406 | { |
| 6407 | const UCHAR* p1 = p; |
| 6408 | UCHAR* p2 = buffer2.getBuffer(len) + len; |
| 6409 | const UCHAR* const end = p1 + len; |
| 6410 | ULONG size = 0; |
| 6411 | |
| 6412 | while (p2 > buffer2.begin()) |
| 6413 | { |
| 6414 | #ifdef DEV_BUILD |
| 6415 | const bool read = |
| 6416 | #endif |
| 6417 | IntlUtil::readOneChar(cs, &p1, end, &size); |
| 6418 | fb_assert(read == true); |
| 6419 | memcpy(p2 -= size, p1, size); |
| 6420 | } |
| 6421 | |
| 6422 | fb_assert(p2 == buffer2.begin()); |
| 6423 | p = p2; |
| 6424 | } |
| 6425 | else |
| 6426 | { |
| 6427 | for (UCHAR* p2 = p + len - 1; p2 >= p; p++, p2--) |
| 6428 | { |
| 6429 | const UCHAR c = *p; |
| 6430 | *p = *p2; |
| 6431 | *p2 = c; |
| 6432 | } |
| 6433 | |
| 6434 | p = buffer.begin(); |
| 6435 | } |
| 6436 | |
| 6437 | EVL_make_value(tdbb, value, impure); |
| 6438 |
nothing calls this directly
no test coverage detected