void reverse_1 (void *base, int n, int elemSize, void (*swapFn) (void *, void *)) { for (int i = 0; i < (n/2); i++){ // find pointer to each element in array // normalize pointer math void *newElemIdx = (char *)base + i * elemSize; void *oldElemIdx = (char *)base + (n -1 - i) * elemSize; // use swap function, dependent on elemSize; swapFn(newElemIdx, oldElemIdx); } }
static void TestSwapCase(UDataMemory *pData, const char *name, UDataSwapFn *swapFn, uint8_t *buffer, uint8_t *buffer2) { UDataSwapper *ds; const void *inData, *inHeader; int32_t length, dataLength, length2, headerLength; UErrorCode errorCode; UBool inEndian, oppositeEndian; uint8_t inCharset, oppositeCharset; inData=udata_getMemory(pData); /* * get the data length if possible, to verify that swapping and preflighting * handles the entire data */ dataLength=udata_getLength(pData); /* * get the header and its length * all of the swap implementation functions require the header to be included */ inHeader=udata_getRawMemory(pData); headerLength=(int32_t)((const char *)inData-(const char *)inHeader); /* first swap to opposite endianness but same charset family */ errorCode=U_ZERO_ERROR; ds=udata_openSwapperForInputData(inHeader, headerLength, !U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &errorCode); if(U_FAILURE(errorCode)) { log_err("udata_openSwapperForInputData(%s->!isBig+same charset) failed - %s\n", name, u_errorName(errorCode)); return; } inEndian=ds->inIsBigEndian; inCharset=ds->inCharset; oppositeEndian=!inEndian; oppositeCharset= inCharset==U_ASCII_FAMILY ? U_EBCDIC_FAMILY : U_ASCII_FAMILY; /* make this test work with data files that are built for a different platform */ if(inEndian!=U_IS_BIG_ENDIAN || inCharset!=U_CHARSET_FAMILY) { udata_closeSwapper(ds); ds=udata_openSwapper(inEndian, inCharset, oppositeEndian, inCharset, &errorCode); if(U_FAILURE(errorCode)) { log_err("udata_openSwapper(%s->!isBig+same charset) failed - %s\n", name, u_errorName(errorCode)); return; } } ds->printError=printError; /* preflight the length */ length=swapFn(ds, inHeader, -1, NULL, &errorCode); if(U_FAILURE(errorCode)) { log_err("swapFn(preflight %s->!isBig+same charset) failed - %s\n", name, u_errorName(errorCode)); udata_closeSwapper(ds); return; } /* compare the preflighted length against the data length */ if(dataLength>=0 && (length+15)<(headerLength+dataLength)) { log_err("swapFn(preflight %s->!isBig+same charset) length too small: %d < data length %d\n", name, length, (headerLength+dataLength)); udata_closeSwapper(ds); return; } /* swap, not in-place */ length2=swapFn(ds, inHeader, length, buffer, &errorCode); udata_closeSwapper(ds); if(U_FAILURE(errorCode)) { log_err("swapFn(%s->!isBig+same charset) failed - %s\n", name, u_errorName(errorCode)); return; } /* compare the swap length against the preflighted length */ if(length2!=length) { log_err("swapFn(%s->!isBig+same charset) length differs from preflighting: %d != preflighted %d\n", name, length2, length); return; } /* next swap to opposite charset family */ ds=udata_openSwapper(oppositeEndian, inCharset, oppositeEndian, oppositeCharset, &errorCode); if(U_FAILURE(errorCode)) { log_err("udata_openSwapper(%s->!isBig+other charset) failed - %s\n", name, u_errorName(errorCode)); return; } ds->printError=printError; /* swap in-place */ length2=swapFn(ds, buffer, length, buffer, &errorCode); udata_closeSwapper(ds); if(U_FAILURE(errorCode)) { log_err("swapFn(%s->!isBig+other charset) failed - %s\n", name, u_errorName(errorCode)); return; } /* compare the swap length against the original length */ if(length2!=length) { log_err("swapFn(%s->!isBig+other charset) length differs from original: %d != original %d\n", name, length2, length); return; } /* finally swap to original platform values */ ds=udata_openSwapper(oppositeEndian, oppositeCharset, inEndian, inCharset, &errorCode); if(U_FAILURE(errorCode)) { log_err("udata_openSwapper(%s->back to original) failed - %s\n", name, u_errorName(errorCode)); return; } ds->printError=printError; /* swap, not in-place */ length2=swapFn(ds, buffer, length, buffer2, &errorCode); udata_closeSwapper(ds); if(U_FAILURE(errorCode)) { log_err("swapFn(%s->back to original) failed - %s\n", name, u_errorName(errorCode)); return; } /* compare the swap length against the original length */ if(length2!=length) { log_err("swapFn(%s->back to original) length differs from original: %d != original %d\n", name, length2, length); return; } /* compare the final contents with the original */ if(0!=uprv_memcmp(inHeader, buffer2, length)) { const uint8_t *original; uint8_t diff[8]; int32_t i, j; log_err("swapFn(%s->back to original) contents differs from original\n", name); /* find the first difference */ original=(const uint8_t *)inHeader; for(i=0; i<length && original[i]==buffer2[i]; ++i) {} /* find the next byte that is the same */ for(j=i+1; j<length && original[j]!=buffer2[j]; ++j) {} log_info(" difference at index %d=0x%x, until index %d=0x%x\n", i, i, j, j); /* round down to the last 4-boundary for better result output */ i&=~3; log_info("showing bytes from index %d=0x%x (length %d=0x%x):\n", i, i, length, length); /* print 8 bytes but limit to the buffer contents */ length2=i+sizeof(diff); if(length2>length) { length2=length; } /* print the original bytes */ uprv_memset(diff, 0, sizeof(diff)); for(j=i; j<length2; ++j) { diff[j-i]=original[j]; } log_info(" original: %02x %02x %02x %02x %02x %02x %02x %02x\n", diff[0], diff[1], diff[2], diff[3], diff[4], diff[5], diff[6], diff[7]); /* print the swapped bytes */ uprv_memset(diff, 0, sizeof(diff)); for(j=i; j<length2; ++j) { diff[j-i]=buffer2[j]; } log_info(" swapped: %02x %02x %02x %02x %02x %02x %02x %02x\n", diff[0], diff[1], diff[2], diff[3], diff[4], diff[5], diff[6], diff[7]); } }