Tegyük fel, hogy be kell szúrnunk egy stream közepébe adatot. Beszúrás alatt azt értem, hogy nem felülírom ami útban van, hanem a beszúrt terület mögé mozgatom. Hogy lehet ezt csinálni? A memcpy() nem feltétlen jó, hiszen, ha a beszúrt terület vége nem lóg túl a stream eredeti végén, akkor a beszúrandó méret kisebb lesz, mint az a terület ami mögötte van, ennek megfelelően a copynál akkora overlap lesz, mint ide Irak és saját magára fog másolni, felülírván a hátralévő adatokat. A memmove() már jobb lenne, mert annek nem baj az overlap...csak éppen ez úgy működik, hogy előbb átmásolja egy átmeneti bufferbe, aztán copyzza be a végső helyére. Pazarlás Safranek. Hogyan lehetne ezt egyszeri memóriamásolással megoldani? Kurwa egyszerű, ha a sima memcpy() azért nem jó ide, mert overlap esetén felülírja a hátralévő adatokat, akkor fordított irányban kell copyzni! Viszont olyan memóriamásoló függvény, ami ezt csinálná, egyszerűen nincs! (Stringmásolóra vannak implementációk, de az nem jó, az byte-onként másol.)
Úgyhogy összedobtam egyet. Használlyátok egész seggel:#ifndef _MEMCPY_BKW_C
#define _MEMCPY_BKW_C 1
#include <stdint.h>
#include <stdlib.h>
#if __WORDSIZE == 64
#define mask 7
#define shift 3
#define copytype int64_t
#endif
#if __WORDSIZE == 32
#define mask 3
#define shift 2
#define copytype int32_t
#endif
#if __WORDSIZE == 16
#define mask 1
#define shift 1
#define copytype int16_t
#endif
void memcpy_bkw(char *dst, char *src, size_t size)
{
size_t mod;
copytype *dstb;
copytype *srcb;
dstb = (copytype *)((copytype)dst + size);
srcb = (copytype *)((copytype)src + size);
mod = size & mask;
size >>= shift;
while (size--)
{
*dstb-- = *srcb--;
}
while (mod--)
{
*dst-- = *src--;
}
}
#endif |