diff options
Diffstat (limited to 'src/H5V.c')
-rw-r--r-- | src/H5V.c | 1712 |
1 files changed, 0 insertions, 1712 deletions
diff --git a/src/H5V.c b/src/H5V.c deleted file mode 100644 index 3277b90..0000000 --- a/src/H5V.c +++ /dev/null @@ -1,1712 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the files COPYING and Copyright.html. COPYING can be found at the root * - * of the source code distribution tree; Copyright.html can be found at the * - * root level of an installed copy of the electronic HDF5 document set and * - * is linked from the top-level documents page. It can also be found at * - * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Programmer: Robb Matzke <matzke@llnl.gov> - * Friday, October 10, 1997 - */ - - -#include "H5private.h" -#include "H5Eprivate.h" -#include "H5Oprivate.h" -#include "H5Vprivate.h" - -/* Local typedefs */ -typedef struct H5V_memcpy_ud_t { - unsigned char *dst; /* Pointer to destination buffer */ - const unsigned char *src; /* Pointer to source buffer */ -} H5V_memcpy_ud_t; - -/* Local macros */ -#define H5V_HYPER_NDIMS H5O_LAYOUT_NDIMS - -/* Local prototypes */ -static void -H5V_stride_optimize1(unsigned *np/*in,out*/, hsize_t *elmt_size/*in,out*/, - const hsize_t *size, hsize_t *stride1); -static void -H5V_stride_optimize2(unsigned *np/*in,out*/, hsize_t *elmt_size/*in,out*/, - const hsize_t *size, hsize_t *stride1, hsize_t *stride2); -#ifdef LATER -static void -H5V_stride_copy2(hsize_t nelmts, hsize_t elmt_size, - unsigned dst_n, const hsize_t *dst_size, const ssize_t *dst_stride, void *_dst, - unsigned src_n, const hsize_t *src_size, const ssize_t *src_stride, const void *_src); -#endif /* LATER */ - - -/*------------------------------------------------------------------------- - * Function: H5V_stride_optimize1 - * - * Purpose: Given a stride vector which references elements of the - * specified size, optimize the dimensionality, the stride - * vector, and the element size to minimize the dimensionality - * and the number of memory accesses. - * - * All arguments are passed by reference and their values may be - * modified by this function. - * - * Return: None - * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static void -H5V_stride_optimize1(unsigned *np/*in,out*/, hsize_t *elmt_size/*in,out*/, - const hsize_t *size, hsize_t *stride1) -{ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* - * This has to be true because if we optimize the dimensionality down to - * zero we still must make one reference. - */ - HDassert(1 == H5V_vector_reduce_product(0, NULL)); - - /* - * Combine adjacent memory accesses - */ - while (*np && stride1[*np-1]>0 && - (hsize_t)(stride1[*np-1])==*elmt_size) { - *elmt_size *= size[*np-1]; - if (--*np) - stride1[*np-1] += size[*np] * stride1[*np]; - } - - FUNC_LEAVE_NOAPI_VOID -} - - -/*------------------------------------------------------------------------- - * Function: H5V_stride_optimize2 - * - * Purpose: Given two stride vectors which reference elements of the - * specified size, optimize the dimensionality, the stride - * vectors, and the element size to minimize the dimensionality - * and the number of memory accesses. - * - * All arguments are passed by reference and their values may be - * modified by this function. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 - * - * Modifications: - * Unrolled loops for common cases - * Quincey Koziol - * ?, ? ?, 2001? - * - *------------------------------------------------------------------------- - */ -static void -H5V_stride_optimize2(unsigned *np/*in,out*/, hsize_t *elmt_size/*in,out*/, - const hsize_t *size, hsize_t *stride1, hsize_t *stride2) -{ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* - * This has to be true because if we optimize the dimensionality down to - * zero we still must make one reference. - */ - HDassert(1 == H5V_vector_reduce_product(0, NULL)); - HDassert(*elmt_size>0); - - /* - * Combine adjacent memory accesses - */ - - /* Unroll loop for common cases */ - switch(*np) { - case 1: /* For 0-D datasets (dunno if this ever gets used...) */ - if(stride1[0] == *elmt_size && stride2[0] == *elmt_size) { - *elmt_size *= size[0]; - --*np; /* *np decrements to a value of 0 now */ - } /* end if */ - break; - - case 2: /* For 1-D datasets */ - if(stride1[1] == *elmt_size && stride2[1] == *elmt_size) { - *elmt_size *= size[1]; - --*np; /* *np decrements to a value of 1 now */ - stride1[0] += size[1] * stride1[1]; - stride2[0] += size[1] * stride2[1]; - - if(stride1[0] == *elmt_size && stride2[0] == *elmt_size) { - *elmt_size *= size[0]; - --*np; /* *np decrements to a value of 0 now */ - } /* end if */ - } /* end if */ - break; - - case 3: /* For 2-D datasets */ - if(stride1[2] == *elmt_size && stride2[2] == *elmt_size) { - *elmt_size *= size[2]; - --*np; /* *np decrements to a value of 2 now */ - stride1[1] += size[2] * stride1[2]; - stride2[1] += size[2] * stride2[2]; - - if(stride1[1] == *elmt_size && stride2[1] == *elmt_size) { - *elmt_size *= size[1]; - --*np; /* *np decrements to a value of 1 now */ - stride1[0] += size[1] * stride1[1]; - stride2[0] += size[1] * stride2[1]; - - if(stride1[0] == *elmt_size && stride2[0] == *elmt_size) { - *elmt_size *= size[0]; - --*np; /* *np decrements to a value of 0 now */ - } /* end if */ - } /* end if */ - } /* end if */ - break; - - case 4: /* For 3-D datasets */ - if(stride1[3] == *elmt_size && stride2[3] == *elmt_size) { - *elmt_size *= size[3]; - --*np; /* *np decrements to a value of 3 now */ - stride1[2] += size[3] * stride1[3]; - stride2[2] += size[3] * stride2[3]; - - if(stride1[2] == *elmt_size && stride2[2] == *elmt_size) { - *elmt_size *= size[2]; - --*np; /* *np decrements to a value of 2 now */ - stride1[1] += size[2] * stride1[2]; - stride2[1] += size[2] * stride2[2]; - - if(stride1[1] == *elmt_size && stride2[1] == *elmt_size) { - *elmt_size *= size[1]; - --*np; /* *np decrements to a value of 1 now */ - stride1[0] += size[1] * stride1[1]; - stride2[0] += size[1] * stride2[1]; - - if(stride1[0] == *elmt_size && stride2[0] == *elmt_size) { - *elmt_size *= size[0]; - --*np; /* *np decrements to a value of 0 now */ - } /* end if */ - } /* end if */ - } /* end if */ - } /* end if */ - break; - - default: - while (*np && - stride1[*np-1] == *elmt_size && - stride2[*np-1] == *elmt_size) { - *elmt_size *= size[*np-1]; - if (--*np) { - stride1[*np-1] += size[*np] * stride1[*np]; - stride2[*np-1] += size[*np] * stride2[*np]; - } - } - break; - } /* end switch */ - - FUNC_LEAVE_NOAPI_VOID -} - - -/*------------------------------------------------------------------------- - * Function: H5V_hyper_stride - * - * Purpose: Given a description of a hyperslab, this function returns - * (through STRIDE[]) the byte strides appropriate for accessing - * all bytes of the hyperslab and the byte offset where the - * striding will begin. The SIZE can be passed to the various - * stride functions. - * - * The dimensionality of the whole array, the hyperslab, and the - * returned stride array is N. The whole array dimensions are - * TOTAL_SIZE and the hyperslab is at offset OFFSET and has - * dimensions SIZE. - * - * The stride and starting point returned will cause the - * hyperslab elements to be referenced in C order. - * - * Return: Success: Byte offset from beginning of array to start - * of striding. - * - * Failure: abort() -- should never fail - * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 - * - * Modifications: - * Unrolled loops for common cases - * Quincey Koziol - * ?, ? ?, 2001? - * - *------------------------------------------------------------------------- - */ -hsize_t -H5V_hyper_stride(unsigned n, const hsize_t *size, - const hsize_t *total_size, const hsize_t *offset, - hsize_t *stride/*out*/) -{ - hsize_t skip; /*starting point byte offset */ - hsize_t acc; /*accumulator */ - int i; /*counter */ - hsize_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(n <= H5V_HYPER_NDIMS); - HDassert(size); - HDassert(total_size); - HDassert(stride); - - /* init */ - HDassert(n>0); - stride[n-1] = 1; - skip = offset ? offset[n-1] : 0; - - switch(n) { - case 2: /* 1-D dataset */ - HDassert(total_size[1]>=size[1]); - stride[0] = total_size[1]-size[1]; /*overflow checked*/ - acc = total_size[1]; - skip += acc * (offset ? offset[0] : 0); - break; - - case 3: /* 2-D dataset */ - HDassert(total_size[2]>=size[2]); - stride[1] = total_size[2]-size[2]; /*overflow checked*/ - acc = total_size[2]; - skip += acc * (offset ? (hsize_t)offset[1] : 0); - - HDassert(total_size[1]>=size[1]); - stride[0] = acc * (total_size[1] - size[1]); /*overflow checked*/ - acc *= total_size[1]; - skip += acc * (offset ? (hsize_t)offset[0] : 0); - break; - - case 4: /* 3-D dataset */ - HDassert(total_size[3]>=size[3]); - stride[2] = total_size[3]-size[3]; /*overflow checked*/ - acc = total_size[3]; - skip += acc * (offset ? (hsize_t)offset[2] : 0); - - HDassert(total_size[2]>=size[2]); - stride[1] = acc * (total_size[2] - size[2]); /*overflow checked*/ - acc *= total_size[2]; - skip += acc * (offset ? (hsize_t)offset[1] : 0); - - HDassert(total_size[1]>=size[1]); - stride[0] = acc * (total_size[1] - size[1]); /*overflow checked*/ - acc *= total_size[1]; - skip += acc * (offset ? (hsize_t)offset[0] : 0); - break; - - default: - /* others */ - for (i=(int)(n-2), acc=1; i>=0; --i) { - HDassert(total_size[i+1]>=size[i+1]); - stride[i] = acc * (total_size[i+1] - size[i+1]); /*overflow checked*/ - acc *= total_size[i+1]; - skip += acc * (offset ? (hsize_t)offset[i] : 0); - } - break; - } /* end switch */ - - /* Set return value */ - ret_value=skip; - - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5V_hyper_eq - * - * Purpose: Determines whether two hyperslabs are equal. This function - * assumes that both hyperslabs are relative to the same array, - * for if not, they could not possibly be equal. - * - * Return: Success: TRUE if the hyperslabs are equal (that is, - * both refer to exactly the same elements of an - * array) - * - * FALSE otherwise. - * - * Failure: TRUE the rank is zero or if both hyperslabs - * are of zero size. - * - * Programmer: Robb Matzke - * Friday, October 17, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -htri_t -H5V_hyper_eq(unsigned n, - const hsize_t *offset1, const hsize_t *size1, - const hsize_t *offset2, const hsize_t *size2) -{ - hsize_t nelmts1 = 1, nelmts2 = 1; - unsigned i; - htri_t ret_value=TRUE; /* Return value */ - - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - if (n == 0) HGOTO_DONE(TRUE) - - for (i=0; i<n; i++) { - if ((offset1 ? offset1[i] : 0) != (offset2 ? offset2[i] : 0)) - HGOTO_DONE(FALSE) - if ((size1 ? size1[i] : 0) != (size2 ? size2[i] : 0)) - HGOTO_DONE(FALSE) - if (0 == (nelmts1 *= (size1 ? size1[i] : 0))) - HGOTO_DONE(FALSE) - if (0 == (nelmts2 *= (size2 ? size2[i] : 0))) - HGOTO_DONE(FALSE) - } - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5V_hyper_disjointp - * - * Purpose: Determines if two hyperslabs are disjoint. - * - * Return: Success: FALSE if they are not disjoint. - * TRUE if they are disjoint. - * - * Failure: A hyperslab of zero size is disjoint from all - * other hyperslabs. - * - * Programmer: Robb Matzke - * Thursday, October 16, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -htri_t -H5V_hyper_disjointp(unsigned n, - const hsize_t *offset1, const uint32_t *size1, - const hsize_t *offset2, const uint32_t *size2) -{ - unsigned u; - htri_t ret_value = FALSE; /* Return value */ - - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - if(!n || !size1 || !size2) - HGOTO_DONE(TRUE) - - for(u = 0; u < n; u++) { - HDassert(size1[u] < HSIZET_MAX); - HDassert(size2[u] < HSIZET_MAX); - - if(0 == size1[u] || 0 == size2[u]) - HGOTO_DONE(TRUE) - if(((offset1 ? offset1[u] : 0) < (offset2 ? offset2[u] : 0) && - ((offset1 ? offset1[u] : 0) + size1[u] <= (offset2 ? offset2[u] : 0))) || - ((offset2 ? offset2[u] : 0) < (offset1 ? offset1[u] : 0) && - ((offset2 ? offset2[u] : 0) + size2[u] <= (offset1 ? offset1[u] : 0)))) - HGOTO_DONE(TRUE) - } /* end for */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5V_hyper_disjointp() */ - - -/*------------------------------------------------------------------------- - * Function: H5V_hyper_fill - * - * Purpose: Similar to memset() except it operates on hyperslabs... - * - * Fills a hyperslab of array BUF with some value VAL. BUF - * is treated like a C-order array with N dimensions where the - * size of each dimension is TOTAL_SIZE[]. The hyperslab which - * will be filled with VAL begins at byte offset OFFSET[] from - * the minimum corner of BUF and continues for SIZE[] bytes in - * each dimension. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Friday, October 10, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5V_hyper_fill(unsigned n, const hsize_t *_size, - const hsize_t *total_size, const hsize_t *offset, void *_dst, - unsigned fill_value) -{ - uint8_t *dst = (uint8_t*)_dst; /*cast for ptr arithmetic */ - hsize_t size[H5V_HYPER_NDIMS]; /*a modifiable copy of _size */ - hsize_t dst_stride[H5V_HYPER_NDIMS]; /*destination stride info */ - hsize_t dst_start; /*byte offset to start of stride*/ - hsize_t elmt_size = 1; /*bytes per element */ - herr_t ret_value; /*function return status */ -#ifndef NDEBUG - unsigned u; -#endif - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* check args */ - HDassert(n > 0 && n <= H5V_HYPER_NDIMS); - HDassert(_size); - HDassert(total_size); - HDassert(dst); -#ifndef NDEBUG - for (u = 0; u < n; u++) { - HDassert(_size[u] > 0); - HDassert(total_size[u] > 0); - } -#endif - - /* Copy the size vector so we can modify it */ - H5V_vector_cpy(n, size, _size); - - /* Compute an optimal destination stride vector */ - dst_start = H5V_hyper_stride(n, size, total_size, offset, dst_stride); - H5V_stride_optimize1(&n, &elmt_size, size, dst_stride); - - /* Copy */ - ret_value = H5V_stride_fill(n, elmt_size, size, dst_stride, dst+dst_start, - fill_value); - - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5V_hyper_copy - * - * Purpose: Copies a hyperslab from the source to the destination. - * - * A hyperslab is a logically contiguous region of - * multi-dimensional size SIZE of an array whose dimensionality - * is N and whose total size is DST_TOTAL_SIZE or SRC_TOTAL_SIZE. - * The minimum corner of the hyperslab begins at a - * multi-dimensional offset from the minimum corner of the DST - * (destination) or SRC (source) array. The sizes and offsets - * are assumed to be in C order, that is, the first size/offset - * varies the slowest while the last varies the fastest in the - * mapping from N-dimensional space to linear space. This - * function assumes that the array elements are single bytes (if - * your array has multi-byte elements then add an additional - * dimension whose size is that of your element). - * - * The SRC and DST array may be the same array, but the results - * are undefined if the source hyperslab overlaps the - * destination hyperslab. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Friday, October 10, 1997 - * - * Modifications: - * Unrolled loops for common cases - * Quincey Koziol - * ?, ? ?, 2001? - * - *------------------------------------------------------------------------- - */ -herr_t -H5V_hyper_copy(unsigned n, const hsize_t *_size, - - /*destination*/ - const hsize_t *dst_size, const hsize_t *dst_offset, - void *_dst, - - /*source*/ - const hsize_t *src_size, const hsize_t *src_offset, - const void *_src) -{ - const uint8_t *src = (const uint8_t*)_src; /*cast for ptr arithmtc */ - uint8_t *dst = (uint8_t*) _dst; /*cast for ptr arithmtc */ - hsize_t size[H5V_HYPER_NDIMS]; /*a modifiable _size */ - hsize_t src_stride[H5V_HYPER_NDIMS]; /*source stride info */ - hsize_t dst_stride[H5V_HYPER_NDIMS]; /*dest stride info */ - hsize_t dst_start, src_start; /*offset to start at */ - hsize_t elmt_size = 1; /*element size in bytes */ - herr_t ret_value; /*return status */ -#ifndef NDEBUG - unsigned u; -#endif - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* check args */ - HDassert(n > 0 && n <= H5V_HYPER_NDIMS); - HDassert(_size); - HDassert(dst_size); - HDassert(src_size); - HDassert(dst); - HDassert(src); -#ifndef NDEBUG - for (u = 0; u < n; u++) { - HDassert(_size[u] > 0); - HDassert(dst_size[u] > 0); - HDassert(src_size[u] > 0); - } -#endif - - /* Copy the size vector so we can modify it */ - H5V_vector_cpy(n, size, _size); - - /* Compute stride vectors for source and destination */ -#ifdef NO_INLINED_CODE - dst_start = H5V_hyper_stride(n, size, dst_size, dst_offset, dst_stride); - src_start = H5V_hyper_stride(n, size, src_size, src_offset, src_stride); -#else /* NO_INLINED_CODE */ - /* in-line version of two calls to H5V_hyper_stride() */ - { - hsize_t dst_acc; /*accumulator */ - hsize_t src_acc; /*accumulator */ - int ii; /*counter */ - - /* init */ - HDassert(n>0); - dst_stride[n-1] = 1; - src_stride[n-1] = 1; - dst_start = dst_offset ? dst_offset[n-1] : 0; - src_start = src_offset ? src_offset[n-1] : 0; - - /* Unroll loop for common cases */ - switch(n) { - case 2: - HDassert(dst_size[1]>=size[1]); - HDassert(src_size[1]>=size[1]); - dst_stride[0] = dst_size[1] - size[1]; /*overflow checked*/ - src_stride[0] = src_size[1] - size[1]; /*overflow checked*/ - dst_acc = dst_size[1]; - src_acc = src_size[1]; - dst_start += dst_acc * (dst_offset ? dst_offset[0] : 0); - src_start += src_acc * (src_offset ? src_offset[0] : 0); - break; - - case 3: - HDassert(dst_size[2]>=size[2]); - HDassert(src_size[2]>=size[2]); - dst_stride[1] = dst_size[2] - size[2]; /*overflow checked*/ - src_stride[1] = src_size[2] - size[2]; /*overflow checked*/ - dst_acc = dst_size[2]; - src_acc = src_size[2]; - dst_start += dst_acc * (dst_offset ? dst_offset[1] : 0); - src_start += src_acc * (src_offset ? src_offset[1] : 0); - - HDassert(dst_size[1]>=size[1]); - HDassert(src_size[1]>=size[1]); - dst_stride[0] = dst_acc * (dst_size[1] - size[1]); /*overflow checked*/ - src_stride[0] = src_acc * (src_size[1] - size[1]); /*overflow checked*/ - dst_acc *= dst_size[1]; - src_acc *= src_size[1]; - dst_start += dst_acc * (dst_offset ? dst_offset[0] : 0); - src_start += src_acc * (src_offset ? src_offset[0] : 0); - break; - - case 4: - HDassert(dst_size[3]>=size[3]); - HDassert(src_size[3]>=size[3]); - dst_stride[2] = dst_size[3] - size[3]; /*overflow checked*/ - src_stride[2] = src_size[3] - size[3]; /*overflow checked*/ - dst_acc = dst_size[3]; - src_acc = src_size[3]; - dst_start += dst_acc * (dst_offset ? dst_offset[2] : 0); - src_start += src_acc * (src_offset ? src_offset[2] : 0); - - HDassert(dst_size[2]>=size[2]); - HDassert(src_size[2]>=size[2]); - dst_stride[1] = dst_acc * (dst_size[2] - size[2]); /*overflow checked*/ - src_stride[1] = src_acc * (src_size[2] - size[2]); /*overflow checked*/ - dst_acc *= dst_size[2]; - src_acc *= src_size[2]; - dst_start += dst_acc * (dst_offset ? dst_offset[1] : 0); - src_start += src_acc * (src_offset ? src_offset[1] : 0); - - HDassert(dst_size[1]>=size[1]); - HDassert(src_size[1]>=size[1]); - dst_stride[0] = dst_acc * (dst_size[1] - size[1]); /*overflow checked*/ - src_stride[0] = src_acc * (src_size[1] - size[1]); /*overflow checked*/ - dst_acc *= dst_size[1]; - src_acc *= src_size[1]; - dst_start += dst_acc * (dst_offset ? dst_offset[0] : 0); - src_start += src_acc * (src_offset ? src_offset[0] : 0); - break; - - default: - /* others */ - for (ii=(int)(n-2), dst_acc=1, src_acc=1; ii>=0; --ii) { - HDassert(dst_size[ii+1]>=size[ii+1]); - HDassert(src_size[ii+1]>=size[ii+1]); - dst_stride[ii] = dst_acc * (dst_size[ii+1] - size[ii+1]); /*overflow checked*/ - src_stride[ii] = src_acc * (src_size[ii+1] - size[ii+1]); /*overflow checked*/ - dst_acc *= dst_size[ii+1]; - src_acc *= src_size[ii+1]; - dst_start += dst_acc * (dst_offset ? dst_offset[ii] : 0); - src_start += src_acc * (src_offset ? src_offset[ii] : 0); - } - break; - } /* end switch */ - } -#endif /* NO_INLINED_CODE */ - - /* Optimize the strides as a pair */ - H5V_stride_optimize2(&n, &elmt_size, size, dst_stride, src_stride); - - /* Perform the copy in terms of stride */ - ret_value = H5V_stride_copy(n, elmt_size, size, - dst_stride, dst+dst_start, src_stride, src+src_start); - - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5V_stride_fill - * - * Purpose: Fills all bytes of a hyperslab with the same value using - * memset(). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5V_stride_fill(unsigned n, hsize_t elmt_size, const hsize_t *size, - const hsize_t *stride, void *_dst, unsigned fill_value) -{ - uint8_t *dst = (uint8_t*)_dst; /*cast for ptr arithmetic */ - hsize_t idx[H5V_HYPER_NDIMS]; /*1-origin indices */ - hsize_t nelmts; /*number of elements to fill */ - hsize_t i; /*counter */ - int j; /*counter */ - hbool_t carry; /*subtraction carray value */ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(elmt_size < SIZET_MAX); - - H5V_vector_cpy(n, idx, size); - nelmts = H5V_vector_reduce_product(n, size); - for (i=0; i<nelmts; i++) { - /* Copy an element */ - H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); - HDmemset(dst, (int)fill_value, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ - - /* Decrement indices and advance pointer */ - for (j=(int)(n-1), carry=TRUE; j>=0 && carry; --j) { - dst += stride[j]; - - if (--idx[j]) - carry = FALSE; - else { - HDassert(size); - idx[j] = size[j]; - } /* end else */ - } - } - - FUNC_LEAVE_NOAPI(SUCCEED) -} - - -/*------------------------------------------------------------------------- - * Function: H5V_stride_copy - * - * Purpose: Uses DST_STRIDE and SRC_STRIDE to advance through the arrays - * DST and SRC while copying bytes from SRC to DST. This - * function minimizes the number of calls to memcpy() by - * combining various strides, but it will never touch memory - * outside the hyperslab defined by the strides. - * - * Note: If the src_stride is all zero and elmt_size is one, then it's - * probably more efficient to use H5V_stride_fill() instead. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5V_stride_copy(unsigned n, hsize_t elmt_size, const hsize_t *size, - const hsize_t *dst_stride, void *_dst, - const hsize_t *src_stride, const void *_src) -{ - uint8_t *dst = (uint8_t*)_dst; /*cast for ptr arithmetic*/ - const uint8_t *src = (const uint8_t*) _src; /*cast for ptr arithmetic*/ - hsize_t idx[H5V_HYPER_NDIMS]; /*1-origin indices */ - hsize_t nelmts; /*num elements to copy */ - hsize_t i; /*counter */ - int j; /*counters */ - hbool_t carry; /*carray for subtraction*/ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(elmt_size<SIZET_MAX); - - if (n) { - H5V_vector_cpy(n, idx, size); - nelmts = H5V_vector_reduce_product(n, size); - for (i=0; i<nelmts; i++) { - - /* Copy an element */ - H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); - HDmemcpy(dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ - - /* Decrement indices and advance pointers */ - for (j=(int)(n-1), carry=TRUE; j>=0 && carry; --j) { - src += src_stride[j]; - dst += dst_stride[j]; - - if (--idx[j]) - carry = FALSE; - else { - HDassert(size); - idx[j] = size[j]; - } - } - } - } else { - H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); - HDmemcpy (dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ - } - - FUNC_LEAVE_NOAPI(SUCCEED) -} - - -/*------------------------------------------------------------------------- - * Function: H5V_stride_copy_s - * - * Purpose: Uses DST_STRIDE and SRC_STRIDE to advance through the arrays - * DST and SRC while copying bytes from SRC to DST. This - * function minimizes the number of calls to memcpy() by - * combining various strides, but it will never touch memory - * outside the hyperslab defined by the strides. - * - * Note: If the src_stride is all zero and elmt_size is one, then it's - * probably more efficient to use H5V_stride_fill() instead. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5V_stride_copy_s(unsigned n, hsize_t elmt_size, const hsize_t *size, - const hssize_t *dst_stride, void *_dst, - const hssize_t *src_stride, const void *_src) -{ - uint8_t *dst = (uint8_t*)_dst; /*cast for ptr arithmetic*/ - const uint8_t *src = (const uint8_t*) _src; /*cast for ptr arithmetic*/ - hsize_t idx[H5V_HYPER_NDIMS]; /*1-origin indices */ - hsize_t nelmts; /*num elements to copy */ - hsize_t i; /*counter */ - int j; /*counters */ - hbool_t carry; /*carray for subtraction*/ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(elmt_size<SIZET_MAX); - - if (n) { - H5V_vector_cpy(n, idx, size); - nelmts = H5V_vector_reduce_product(n, size); - for (i=0; i<nelmts; i++) { - - /* Copy an element */ - H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); - HDmemcpy(dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ - - /* Decrement indices and advance pointers */ - for (j=(int)(n-1), carry=TRUE; j>=0 && carry; --j) { - src += src_stride[j]; - dst += dst_stride[j]; - - if (--idx[j]) - carry = FALSE; - else { - HDassert(size); - idx[j] = size[j]; - } - } - } - } else { - H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); - HDmemcpy (dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ - } - - FUNC_LEAVE_NOAPI(SUCCEED) -} - -#ifdef LATER - -/*------------------------------------------------------------------------- - * Function: H5V_stride_copy2 - * - * Purpose: Similar to H5V_stride_copy() except the source and - * destination each have their own dimensionality and size and - * we copy exactly NELMTS elements each of size ELMT_SIZE. The - * size counters wrap if NELMTS is more than a size counter. - * - * Return: None - * - * Programmer: Robb Matzke - * Saturday, October 11, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static void -H5V_stride_copy2(hsize_t nelmts, hsize_t elmt_size, - - /* destination */ - unsigned dst_n, const hsize_t *dst_size, - const hsize_t *dst_stride, - void *_dst, - - /* source */ - unsigned src_n, const hsize_t *src_size, - const hsize_t *src_stride, - const void *_src) -{ - uint8_t *dst = (uint8_t *) _dst; - const uint8_t *src = (const uint8_t *) _src; - hsize_t dst_idx[H5V_HYPER_NDIMS]; - hsize_t src_idx[H5V_HYPER_NDIMS]; - hsize_t i; /* Local index variable */ - int j; /* Local index variable */ - hbool_t carry; - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(elmt_size < SIZET_MAX); - HDassert(dst_n>0); - HDassert(src_n>0); - - H5V_vector_cpy(dst_n, dst_idx, dst_size); - H5V_vector_cpy(src_n, src_idx, src_size); - - for (i=0; i<nelmts; i++) { - - /* Copy an element */ - H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t); - HDmemcpy(dst, src, (size_t)elmt_size); /*lint !e671 The elmt_size will be OK */ - - /* Decrement indices and advance pointers */ - for (j=(int)(dst_n-1), carry=TRUE; j>=0 && carry; --j) { - dst += dst_stride[j]; - if (--dst_idx[j]) - carry = FALSE; - else { - HDassert(dst_size); - dst_idx[j] = dst_size[j]; - } /* end else */ - } - for (j=(int)(src_n-1), carry=TRUE; j>=0 && carry; --j) { - src += src_stride[j]; - if (--src_idx[j]) - carry = FALSE; - else { - HDassert(src_size); - src_idx[j] = src_size[j]; - } /* end else */ - } - } - - FUNC_LEAVE_NOAPI_VOID -} -#endif /* LATER */ - - -/*------------------------------------------------------------------------- - * Function: H5V_array_fill - * - * Purpose: Fills all bytes of an array with the same value using - * memset(). Increases amount copied by power of two until the - * halfway point is crossed, then copies the rest in one swoop. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Thursday, June 18, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5V_array_fill(void *_dst, const void *src, size_t size, size_t count) -{ - size_t copy_size; /* size of the buffer to copy */ - size_t copy_items; /* number of items currently copying*/ - size_t items_left; /* number of items left to copy */ - uint8_t *dst=(uint8_t*)_dst;/* alias for pointer arithmetic */ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(dst); - HDassert(src); - HDassert(size < SIZET_MAX && size > 0); - HDassert(count < SIZET_MAX && count > 0); - - HDmemcpy(dst, src, size); /* copy first item */ - - /* Initialize counters, etc. while compensating for first element copied */ - copy_size = size; - copy_items = 1; - items_left = count - 1; - dst += size; - - /* copy until we've copied at least half of the items */ - while (items_left >= copy_items) - { - HDmemcpy(dst, _dst, copy_size); /* copy the current chunk */ - dst += copy_size; /* move the offset for the next chunk */ - items_left -= copy_items; /* decrement the number of items left */ - - copy_size *= 2; /* increase the size of the chunk to copy */ - copy_items *= 2; /* increase the count of items we are copying */ - } /* end while */ - if (items_left > 0) /* if there are any items left to copy */ - HDmemcpy(dst, _dst, items_left * size); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5V_array_fill() */ - - -/*------------------------------------------------------------------------- - * Function: H5V_array_down - * - * Purpose: Given a set of dimension sizes, calculate the size of each - * "down" slice. This is the size of the dimensions for all the - * dimensions below the current one, which is used for indexing - * offsets in this dimension. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, April 28, 2003 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5V_array_down(unsigned n, const hsize_t *total_size, hsize_t *down) -{ - hsize_t acc; /*accumulator */ - int i; /*counter */ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(n <= H5V_HYPER_NDIMS); - HDassert(total_size); - HDassert(down); - - /* Build the sizes of each dimension in the array */ - /* (From fastest to slowest) */ - for(i=(int)(n-1),acc=1; i>=0; i--) { - down[i]=acc; - acc *= total_size[i]; - } /* end for */ - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5V_array_down() */ - - -/*------------------------------------------------------------------------- - * Function: H5V_array_offset_pre - * - * Purpose: Given a coordinate description of a location in an array, this - * function returns the byte offset of the coordinate. - * - * The dimensionality of the whole array, and the offset is N. - * The whole array dimensions are TOTAL_SIZE and the coordinate - * is at offset OFFSET. - * - * Return: Success: Byte offset from beginning of array to element offset - * Failure: abort() -- should never fail - * - * Programmer: Quincey Koziol - * Tuesday, June 22, 1999 - * - * Modifications: - * Use precomputed accumulator array - * Quincey Koziol - * Saturday, April 26, 2003 - * - *------------------------------------------------------------------------- - */ -hsize_t -H5V_array_offset_pre(unsigned n, const hsize_t *acc, const hsize_t *offset) -{ - int i; /*counter */ - hsize_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(n <= H5V_HYPER_NDIMS); - HDassert(acc); - HDassert(offset); - - /* Compute offset in array */ - for (i=(int)(n-1), ret_value=0; i>=0; --i) - ret_value += acc[i] * offset[i]; - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5V_array_offset_pre() */ - - -/*------------------------------------------------------------------------- - * Function: H5V_array_offset - * - * Purpose: Given a coordinate description of a location in an array, this - * function returns the byte offset of the coordinate. - * - * The dimensionality of the whole array, and the offset is N. - * The whole array dimensions are TOTAL_SIZE and the coordinate - * is at offset OFFSET. - * - * Return: Success: Byte offset from beginning of array to element offset - * Failure: abort() -- should never fail - * - * Programmer: Quincey Koziol - * Tuesday, June 22, 1999 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -hsize_t -H5V_array_offset(unsigned n, const hsize_t *total_size, const hsize_t *offset) -{ - hsize_t acc_arr[H5V_HYPER_NDIMS]; /* Accumulated size of down dimensions */ - hsize_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI((HDabort(), 0)) /*lint !e527 Don't worry about unreachable statement */ - - HDassert(n <= H5V_HYPER_NDIMS); - HDassert(total_size); - HDassert(offset); - - /* Build the sizes of each dimension in the array */ - if(H5V_array_down(n,total_size,acc_arr)<0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, UFAIL, "can't compute down sizes") - - /* Set return value */ - ret_value=H5V_array_offset_pre(n,acc_arr,offset); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5V_array_offset() */ - - -/*------------------------------------------------------------------------- - * Function: H5V_array_calc_pre - * - * Purpose: Given a linear offset in an array, the dimensions of that - * array and the pre-computed 'down' (accumulator) sizes, this - * function computes the coordinates of that offset in the array. - * - * The dimensionality of the whole array, and the coordinates is N. - * The array dimensions are TOTAL_SIZE and the coordinates - * are returned in COORD. The linear offset is in OFFSET. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Thursday, July 16, 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5V_array_calc_pre(hsize_t offset, unsigned n, const hsize_t *down, - hsize_t *coords) -{ - unsigned u; /* Local index variable */ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(n <= H5V_HYPER_NDIMS); - HDassert(coords); - - /* Compute the coordinates from the offset */ - for(u = 0; u < n; u++) { - coords[u] = offset / down[u]; - offset %= down[u]; - } /* end for */ - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5V_array_calc_pre() */ - - -/*------------------------------------------------------------------------- - * Function: H5V_array_calc - * - * Purpose: Given a linear offset in an array and the dimensions of that - * array, this function computes the coordinates of that offset - * in the array. - * - * The dimensionality of the whole array, and the coordinates is N. - * The array dimensions are TOTAL_SIZE and the coordinates - * are returned in COORD. The linear offset is in OFFSET. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Wednesday, April 16, 2003 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5V_array_calc(hsize_t offset, unsigned n, const hsize_t *total_size, hsize_t *coords) -{ - hsize_t idx[H5V_HYPER_NDIMS]; /* Size of each dimension in bytes */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity check */ - HDassert(n <= H5V_HYPER_NDIMS); - HDassert(total_size); - HDassert(coords); - - /* Build the sizes of each dimension in the array */ - if(H5V_array_down(n, total_size, idx) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute down sizes") - - /* Compute the coordinates from the offset */ - if(H5V_array_calc_pre(offset, n, idx, coords) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute coordinates") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5V_array_calc() */ - - -/*------------------------------------------------------------------------- - * Function: H5V_chunk_index - * - * Purpose: Given a coordinate offset (COORD), the size of each chunk - * (CHUNK), the number of chunks in each dimension (NCHUNKS) - * and the number of dimensions of all of these (NDIMS), calculate - * a "chunk index" for the chunk that the coordinate offset is - * located in. - * - * The chunk index starts at 0 and increases according to the - * fastest changing dimension, then the next fastest, etc. - * - * For example, with a 3x5 chunk size and 6 chunks in the fastest - * changing dimension and 3 chunks in the slowest changing - * dimension, the chunk indices are as follows: - * - * +-----+-----+-----+-----+-----+-----+ - * | | | | | | | - * | 0 | 1 | 2 | 3 | 4 | 5 | - * | | | | | | | - * +-----+-----+-----+-----+-----+-----+ - * | | | | | | | - * | 6 | 7 | 8 | 9 | 10 | 11 | - * | | | | | | | - * +-----+-----+-----+-----+-----+-----+ - * | | | | | | | - * | 12 | 13 | 14 | 15 | 16 | 17 | - * | | | | | | | - * +-----+-----+-----+-----+-----+-----+ - * - * The chunk index is placed in the CHUNK_IDX location for return - * from this function - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, April 21, 2003 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5V_chunk_index(unsigned ndims, const hsize_t *coord, const uint32_t *chunk, - const hsize_t *down_nchunks, hsize_t *chunk_idx) -{ - hsize_t scaled_coord[H5V_HYPER_NDIMS]; /* Scaled, coordinates, in terms of chunks */ - unsigned u; /* Local index variable */ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(ndims <= H5V_HYPER_NDIMS); - HDassert(coord); - HDassert(chunk); - HDassert(chunk_idx); - - /* Compute the scaled coordinates for actual coordinates */ - for(u=0; u<ndims; u++) - scaled_coord[u]=coord[u]/chunk[u]; - - /* Compute the chunk index */ - *chunk_idx=H5V_array_offset_pre(ndims,down_nchunks,scaled_coord); /*lint !e772 scaled_coord will always be initialized */ - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5V_chunk_index() */ - - -/*------------------------------------------------------------------------- - * Function: H5V_opvv - * - * Purpose: Perform an operation on a source & destination sequences - * of offset/length pairs. Each set of sequnces has an array - * of lengths, an array of offsets, the maximum number of - * sequences and the current sequence to start at in the sequence. - * - * There may be different numbers of bytes in the source and - * destination sequences, the operation stops when either the - * source or destination sequence runs out of information. - * - * Note: The algorithm in this routine is [basically] the same as for - * H5V_memcpyvv(). Changes should be made to both! - * - * Return: Non-negative # of bytes operated on, on success/Negative on failure - * - * Programmer: Quincey Koziol - * Thursday, September 30, 2010 - * - *------------------------------------------------------------------------- - */ -ssize_t -H5V_opvv(size_t dst_max_nseq, size_t *dst_curr_seq, size_t dst_len_arr[], - hsize_t dst_off_arr[], - size_t src_max_nseq, size_t *src_curr_seq, size_t src_len_arr[], - hsize_t src_off_arr[], - H5V_opvv_func_t op, void *op_data) -{ - hsize_t *max_dst_off_ptr, *max_src_off_ptr; /* Pointers to max. source and destination offset locations */ - hsize_t *dst_off_ptr, *src_off_ptr; /* Pointers to source and destination offset arrays */ - size_t *dst_len_ptr, *src_len_ptr; /* Pointers to source and destination length arrays */ - hsize_t tmp_dst_off, tmp_src_off; /* Temporary source and destination offset values */ - size_t tmp_dst_len, tmp_src_len; /* Temporary source and destination length values */ - size_t acc_len; /* Accumulated length of sequences */ - ssize_t ret_value = 0; /* Return value (Total size of sequence in bytes) */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity check */ - HDassert(dst_curr_seq); - HDassert(*dst_curr_seq < dst_max_nseq); - HDassert(dst_len_arr); - HDassert(dst_off_arr); - HDassert(src_curr_seq); - HDassert(*src_curr_seq < src_max_nseq); - HDassert(src_len_arr); - HDassert(src_off_arr); - HDassert(op); - - /* Set initial offset & length pointers */ - dst_len_ptr = dst_len_arr + *dst_curr_seq; - dst_off_ptr = dst_off_arr + *dst_curr_seq; - src_len_ptr = src_len_arr + *src_curr_seq; - src_off_ptr = src_off_arr + *src_curr_seq; - - /* Get temporary source & destination sequence offsets & lengths */ - tmp_dst_len = *dst_len_ptr; - tmp_dst_off = *dst_off_ptr; - tmp_src_len = *src_len_ptr; - tmp_src_off = *src_off_ptr; - - /* Compute maximum offset pointer values */ - max_dst_off_ptr = dst_off_arr + dst_max_nseq; - max_src_off_ptr = src_off_arr + src_max_nseq; - -/* Work through the sequences */ -/* (Choose smallest sequence available initially) */ - - /* Source sequence is less than destination sequence */ - if(tmp_src_len < tmp_dst_len) { -src_smaller: - acc_len = 0; - do { - /* Make operator callback */ - if((*op)(tmp_dst_off, tmp_src_off, tmp_src_len, op_data) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTOPERATE, FAIL, "can't perform operation") - - /* Accumulate number of bytes copied */ - acc_len += tmp_src_len; - - /* Update destination length */ - tmp_dst_off += tmp_src_len; - tmp_dst_len -= tmp_src_len; - - /* Advance source offset & check for being finished */ - src_off_ptr++; - if(src_off_ptr >= max_src_off_ptr) { - /* Roll accumulated changes into appropriate counters */ - *dst_off_ptr = tmp_dst_off; - *dst_len_ptr = tmp_dst_len; - - /* Done with sequences */ - goto finished; - } /* end if */ - tmp_src_off = *src_off_ptr; - - /* Update source information */ - src_len_ptr++; - tmp_src_len = *src_len_ptr; - } while(tmp_src_len < tmp_dst_len); - - /* Roll accumulated sequence lengths into return value */ - ret_value += (ssize_t)acc_len; - - /* Transition to next state */ - if(tmp_dst_len < tmp_src_len) - goto dst_smaller; - else - goto equal; - } /* end if */ - /* Destination sequence is less than source sequence */ - else if(tmp_dst_len < tmp_src_len) { -dst_smaller: - acc_len = 0; - do { - /* Make operator callback */ - if((*op)(tmp_dst_off, tmp_src_off, tmp_dst_len, op_data) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTOPERATE, FAIL, "can't perform operation") - - /* Accumulate number of bytes copied */ - acc_len += tmp_dst_len; - - /* Update source length */ - tmp_src_off += tmp_dst_len; - tmp_src_len -= tmp_dst_len; - - /* Advance destination offset & check for being finished */ - dst_off_ptr++; - if(dst_off_ptr >= max_dst_off_ptr) { - /* Roll accumulated changes into appropriate counters */ - *src_off_ptr = tmp_src_off; - *src_len_ptr = tmp_src_len; - - /* Done with sequences */ - goto finished; - } /* end if */ - tmp_dst_off = *dst_off_ptr; - - /* Update destination information */ - dst_len_ptr++; - tmp_dst_len = *dst_len_ptr; - } while(tmp_dst_len < tmp_src_len); - - /* Roll accumulated sequence lengths into return value */ - ret_value += (ssize_t)acc_len; - - /* Transition to next state */ - if(tmp_src_len < tmp_dst_len) - goto src_smaller; - else - goto equal; - } /* end else-if */ - /* Destination sequence and source sequence are same length */ - else { -equal: - acc_len = 0; - do { - /* Make operator callback */ - if((*op)(tmp_dst_off, tmp_src_off, tmp_dst_len, op_data) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTOPERATE, FAIL, "can't perform operation") - - /* Accumulate number of bytes copied */ - acc_len += tmp_dst_len; - - /* Advance source & destination offset & check for being finished */ - src_off_ptr++; - dst_off_ptr++; - if(src_off_ptr >= max_src_off_ptr || dst_off_ptr >= max_dst_off_ptr) - /* Done with sequences */ - goto finished; - tmp_src_off = *src_off_ptr; - tmp_dst_off = *dst_off_ptr; - - /* Update source information */ - src_len_ptr++; - tmp_src_len = *src_len_ptr; - - /* Update destination information */ - dst_len_ptr++; - tmp_dst_len = *dst_len_ptr; - } while(tmp_dst_len == tmp_src_len); - - /* Roll accumulated sequence lengths into return value */ - ret_value += (ssize_t)acc_len; - - /* Transition to next state */ - if(tmp_dst_len < tmp_src_len) - goto dst_smaller; - else - goto src_smaller; - } /* end else */ - -finished: - /* Roll accumulated sequence lengths into return value */ - ret_value += (ssize_t)acc_len; - - /* Update current sequence vectors */ - *dst_curr_seq = (size_t)(dst_off_ptr - dst_off_arr); - *src_curr_seq = (size_t)(src_off_ptr - src_off_arr); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5V_opvv() */ - - -/*------------------------------------------------------------------------- - * Function: H5V_memcpyvv - * - * Purpose: Given source and destination buffers in memory (SRC & DST) - * copy sequences of from the source buffer into the destination - * buffer. Each set of sequnces has an array of lengths, an - * array of offsets, the maximum number of sequences and the - * current sequence to start at in the sequence. - * - * There may be different numbers of bytes in the source and - * destination sequences, data copying stops when either the - * source or destination buffer runs out of sequence information. - * - * Note: The algorithm in this routine is [basically] the same as for - * H5V_opvv(). Changes should be made to both! - * - * Return: Non-negative # of bytes copied on success/Negative on failure - * - * Programmer: Quincey Koziol - * Friday, May 2, 2003 - * - *------------------------------------------------------------------------- - */ -ssize_t -H5V_memcpyvv(void *_dst, - size_t dst_max_nseq, size_t *dst_curr_seq, size_t dst_len_arr[], hsize_t dst_off_arr[], - const void *_src, - size_t src_max_nseq, size_t *src_curr_seq, size_t src_len_arr[], hsize_t src_off_arr[]) -{ - unsigned char *dst; /* Destination buffer pointer */ - const unsigned char *src; /* Source buffer pointer */ - hsize_t *max_dst_off_ptr, *max_src_off_ptr; /* Pointers to max. source and destination offset locations */ - hsize_t *dst_off_ptr, *src_off_ptr; /* Pointers to source and destination offset arrays */ - size_t *dst_len_ptr, *src_len_ptr; /* Pointers to source and destination length arrays */ - size_t tmp_dst_len; /* Temporary dest. length value */ - size_t tmp_src_len; /* Temporary source length value */ - size_t acc_len; /* Accumulated length of sequences */ - ssize_t ret_value = 0; /* Return value (Total size of sequence in bytes) */ - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(_dst); - HDassert(dst_curr_seq); - HDassert(*dst_curr_seq < dst_max_nseq); - HDassert(dst_len_arr); - HDassert(dst_off_arr); - HDassert(_src); - HDassert(src_curr_seq); - HDassert(*src_curr_seq < src_max_nseq); - HDassert(src_len_arr); - HDassert(src_off_arr); - - /* Set initial offset & length pointers */ - dst_len_ptr = dst_len_arr + *dst_curr_seq; - dst_off_ptr = dst_off_arr + *dst_curr_seq; - src_len_ptr = src_len_arr + *src_curr_seq; - src_off_ptr = src_off_arr + *src_curr_seq; - - /* Get temporary source & destination sequence lengths */ - tmp_dst_len = *dst_len_ptr; - tmp_src_len = *src_len_ptr; - - /* Compute maximum offset pointer values */ - max_dst_off_ptr = dst_off_arr + dst_max_nseq; - max_src_off_ptr = src_off_arr + src_max_nseq; - - /* Compute buffer offsets */ - dst = (unsigned char *)_dst + *dst_off_ptr; - src = (const unsigned char *)_src + *src_off_ptr; - -/* Work through the sequences */ -/* (Choose smallest sequence available initially) */ - - /* Source sequence is less than destination sequence */ - if(tmp_src_len < tmp_dst_len) { -src_smaller: - acc_len = 0; - do { - /* Copy data */ - HDmemcpy(dst, src, tmp_src_len); - - /* Accumulate number of bytes copied */ - acc_len += tmp_src_len; - - /* Update destination length */ - tmp_dst_len -= tmp_src_len; - - /* Advance source offset & check for being finished */ - src_off_ptr++; - if(src_off_ptr >= max_src_off_ptr) { - /* Roll accumulated changes into appropriate counters */ - *dst_off_ptr += acc_len; - *dst_len_ptr = tmp_dst_len; - - /* Done with sequences */ - goto finished; - } /* end if */ - - /* Update destination pointer */ - dst += tmp_src_len; - - /* Update source information */ - src_len_ptr++; - tmp_src_len = *src_len_ptr; - src = (const unsigned char *)_src + *src_off_ptr; - } while(tmp_src_len < tmp_dst_len); - - /* Roll accumulated sequence lengths into return value */ - ret_value += (ssize_t)acc_len; - - /* Transition to next state */ - if(tmp_dst_len < tmp_src_len) - goto dst_smaller; - else - goto equal; - } /* end if */ - /* Destination sequence is less than source sequence */ - else if(tmp_dst_len < tmp_src_len) { -dst_smaller: - acc_len = 0; - do { - /* Copy data */ - HDmemcpy(dst, src, tmp_dst_len); - - /* Accumulate number of bytes copied */ - acc_len += tmp_dst_len; - - /* Update source length */ - tmp_src_len -= tmp_dst_len; - - /* Advance destination offset & check for being finished */ - dst_off_ptr++; - if(dst_off_ptr >= max_dst_off_ptr) { - /* Roll accumulated changes into appropriate counters */ - *src_off_ptr += acc_len; - *src_len_ptr = tmp_src_len; - - /* Done with sequences */ - goto finished; - } /* end if */ - - /* Update source pointer */ - src += tmp_dst_len; - - /* Update destination information */ - dst_len_ptr++; - tmp_dst_len = *dst_len_ptr; - dst = (unsigned char *)_dst + *dst_off_ptr; - } while(tmp_dst_len < tmp_src_len); - - /* Roll accumulated sequence lengths into return value */ - ret_value += (ssize_t)acc_len; - - /* Transition to next state */ - if(tmp_src_len < tmp_dst_len) - goto src_smaller; - else - goto equal; - } /* end else-if */ - /* Destination sequence and source sequence are same length */ - else { -equal: - acc_len = 0; - do { - /* Copy data */ - HDmemcpy(dst, src, tmp_dst_len); - - /* Accumulate number of bytes copied */ - acc_len += tmp_dst_len; - - /* Advance source & destination offset & check for being finished */ - src_off_ptr++; - dst_off_ptr++; - if(src_off_ptr >= max_src_off_ptr || dst_off_ptr >= max_dst_off_ptr) - /* Done with sequences */ - goto finished; - - /* Update source information */ - src_len_ptr++; - tmp_src_len = *src_len_ptr; - src = (const unsigned char *)_src + *src_off_ptr; - - /* Update destination information */ - dst_len_ptr++; - tmp_dst_len = *dst_len_ptr; - dst = (unsigned char *)_dst + *dst_off_ptr; - } while(tmp_dst_len == tmp_src_len); - - /* Roll accumulated sequence lengths into return value */ - ret_value += (ssize_t)acc_len; - - /* Transition to next state */ - if(tmp_dst_len < tmp_src_len) - goto dst_smaller; - else - goto src_smaller; - } /* end else */ - -finished: - /* Roll accumulated sequence lengths into return value */ - ret_value += (ssize_t)acc_len; - - /* Update current sequence vectors */ - *dst_curr_seq = (size_t)(dst_off_ptr - dst_off_arr); - *src_curr_seq = (size_t)(src_off_ptr - src_off_arr); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5V_memcpyvv() */ - |