| 2782 | |
| 2783 | |
| 2784 | static void slice_callback(array_slice* arg, ULONG /*count*/, DSC* descriptors) |
| 2785 | { |
| 2786 | /************************************** |
| 2787 | * |
| 2788 | * s l i c e _ c a l l b a c k |
| 2789 | * |
| 2790 | ************************************** |
| 2791 | * |
| 2792 | * Functional description |
| 2793 | * Perform slice assignment. |
| 2794 | * |
| 2795 | **************************************/ |
| 2796 | thread_db* tdbb = JRD_get_thread_data(); |
| 2797 | |
| 2798 | dsc* array_desc = descriptors; |
| 2799 | dsc* slice_desc = &arg->slice_desc; |
| 2800 | BLOB_PTR* const next = slice_desc->dsc_address + arg->slice_element_length; |
| 2801 | |
| 2802 | if (next > arg->slice_end) |
| 2803 | ERR_post(Arg::Gds(isc_out_of_bounds)); |
| 2804 | |
| 2805 | if (array_desc->dsc_address < arg->slice_base) |
| 2806 | ERR_error(198); // msg 198 array subscript computation error |
| 2807 | |
| 2808 | if (arg->slice_direction == array_slice::slc_writing_array) |
| 2809 | { |
| 2810 | // Storing INTO array |
| 2811 | // FROM slice_desc TO array_desc |
| 2812 | |
| 2813 | // If storing beyond the high-water mark, ensure elements |
| 2814 | // from the high-water mark to current position are zeroed |
| 2815 | |
| 2816 | // Since we are only initializing, it makes sense to throw away |
| 2817 | // the constness of arg->slice_high_water. |
| 2818 | const SLONG l = array_desc->dsc_address - arg->slice_high_water; |
| 2819 | if (l > 0) |
| 2820 | memset(const_cast<BLOB_PTR*>(arg->slice_high_water), 0, l); |
| 2821 | |
| 2822 | // The individual elements of a varying string array may not be aligned |
| 2823 | // correctly. If they aren't, some RISC machines may break. In those |
| 2824 | // cases, calculate the actual length and then move the length and text manually. |
| 2825 | |
| 2826 | if (array_desc->dsc_dtype == dtype_varying && |
| 2827 | array_desc->dsc_address != |
| 2828 | FB_ALIGN(array_desc->dsc_address, (MIN(sizeof(USHORT), FB_ALIGNMENT)))) |
| 2829 | { |
| 2830 | // Note: cannot remove this JRD_get_thread_data without api change |
| 2831 | // to slice callback routines |
| 2832 | /*thread_db* tdbb = */ JRD_get_thread_data(); |
| 2833 | |
| 2834 | DynamicVaryStr<1024> tmp_buffer; |
| 2835 | const USHORT tmp_len = array_desc->dsc_length; |
| 2836 | const char* p; |
| 2837 | const USHORT len = MOV_make_string(tdbb, slice_desc, INTL_TEXT_TYPE(*array_desc), &p, |
| 2838 | tmp_buffer.getBuffer(tmp_len), tmp_len); |
| 2839 | memcpy(array_desc->dsc_address, &len, sizeof(USHORT)); |
| 2840 | memcpy(array_desc->dsc_address + sizeof(USHORT), p, (int) len); |
| 2841 | } |
nothing calls this directly
no test coverage detected