How to Move Data Between Large Overlapping BuffersLast reviewed: July 23, 1997Article ID: Q117743 |
3.10
WINDOWS
kbprg
The information in this article applies to:
SUMMARYProgrammers often need to move large amounts of data between buffers in their applications. The Microsoft Windows version 3.1 API and the Microsoft C Run Time library provide several functions to let you copy and move data between buffers. However, none of these functions guarantees that data larger than 64K can be moved safely between buffers that overlap. This article lists a C function based on the hmemcpy() Windows version 3.1 function to accomplish this job.
MORE INFORMATIONFor example, the functions hmemcpy() and MemoryWrite() handle buffers greater than 64K, but do not guarantee that data can be safely moved between overlapping buffers. The function _fmemmove() guarantees that data can be safely moved between overlapping buffers, but does not handle more than 64K. Below is a C function that provides that functionality. It recognizes and covers the four cases that arise while moving data. The four cases are:
The interface to SafeCopy() is identical to that of hmemcpy().
void SafeCopy(void _huge *d, void _huge *s, long len) { register long i; long safesize, times; // There are four cases to consider // case 1: source and destination are the same // case 2: source and destination do not overlap // case 3: source starts at a location before destination in // linear memory // case 4: source starts at a location after destination in // linear memory // detect case 1 and handle it if (d == s) return; // determine the amount of overlap if (d > s) // get the absolute difference safesize = ((unsigned long)d - (unsigned long)s); else safesize = ((unsigned long)s - (unsigned long)d); // detect case 2 if (safesize >= len) { hmemcpy(d, s, len); // no overlap return; } times = len/safesize; // detect case 3 and handle it if ((s < d) && ((unsigned long)s+len-1) >(unsigned long)d) { // copy bytes from the end of source to the end of // destination in safesize quantum. for (i = 1; i <= times; i++) hmemcpy((void _huge *)((unsigned long) d+len-i*safesize), (void _huge *)((unsigned long)s+len-i*safesize), safesize); // copy the bytes remaining to be copied after // times*safesize bytes have been copied. if (times*safesize < len) hmemcpy(d, s, len - times*safesize); } else // this is case 4. handle it { // ASSERT (s > d) && ((d+len-1) > s)) // copy bytes from the beginning of source to the // beginning of destination in safesize quantum for (i = 0; i < times; i++) hmemcpy((void _huge *)((unsigned long)d+i*safesize), (void _huge *)((unsigned long)s+i*safesize), safesize); // copy the bytes remaining to be copied after // times*safesize bytes have been copied. if (times*safesize < len) hmemcpy((void _huge*)((unsigned long)d+times*safesize), (void _huge*)((unsigned long)s+times*safesize), len - times*safesize); } return; } |
Additional reference words: 3.10
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |