Skip to main content
deleted 74 characters in body; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

Making Multiple Copiesmultiple copies of a Patternpattern

Please refer to my answer for the final version of this function

The protocol on this site is (apparently) to answer your own question with the improved code rather than edit original question. That makes sense otherwise other answers and feedback may be difficult to understand!

Bonus Questionquestion

Making Multiple Copies of a Pattern

Please refer to my answer for the final version of this function

The protocol on this site is (apparently) to answer your own question with the improved code rather than edit original question. That makes sense otherwise other answers and feedback may be difficult to understand!

Bonus Question

Making multiple copies of a pattern

The protocol on this site is (apparently) to answer your own question with the improved code rather than edit original question. That makes sense otherwise other answers and feedback may be difficult to understand!

Bonus question

cross-ref my answer
Source Link
user59064
user59064

Please refer to my answer for the final version of this function

The protocol on this site is (apparently) to answer your own question with the improved code rather than edit original question. That makes sense otherwise other answers and feedback may be difficult to understand!

Please refer to my answer for the final version of this function

The protocol on this site is (apparently) to answer your own question with the improved code rather than edit original question. That makes sense otherwise other answers and feedback may be difficult to understand!

Rollback to Revision 2
Source Link
user59064
user59064

Making multiple copiesMultiple Copies of a patternPattern

#include <string.h> //This is where memcpy() hangs out. I know! I know!

///memcopyfill: Fills a block of memory with a specified pattern. from
///The thetarget addressblock starts at pToFill and extends for pToFillSize bytes.
///The source pattern starts at pFillWith and extends for pFillWithSize bytes.
///Will fill the whole buffer including a trailing partial pattern at the end (if necesssary).
///pFillWithSize must not be 0. pFillWith must not be NULL. 
///If Either pToFill is NULL or pToFillSize is 0, does nothing and returns without error.
///The area to fill and pattern must not overlap or behaviour is undefined.
///Returns 0 on success and non-zero on error.
intvoid memcopyfill(void*const pToFill,const size_t pToFillSize,const void*const  pFillWith,const size_t pFillWithSize){
    if(pToFill==NULL||pToFillSize==0){
        return 0; return;//Nothing to do.
    }
    if(pFillWith==NULL||pFillWithSize==0){
        return 1; return;//ERROR! Something to fillCan anddo nothing to fill it with...
    }
    if(pToFillSize<=pFillWithSizepToFillSize<pFillWithSize){
        memcpy(pToFill,pFillWith,pToFillSize);
        return 0; return;//Short buffer.
    }
    //The to buffer is bigger so we start with a full copy of pattern.
    memcpy(pToFill,pFillWith,pFillWithSize);
    
    //Now we keep doubling the copies by copying and copying from the target onto itself.
    char*lFillFrom=((char*)pToFill)+pFillWithSize;
    size_t lFilledSoFar=pFillWithSize;
    char*lFillEnd=((char*)pToFill)+pToFillSize;
    while(lFilledSoFar<(lFillEnd-lFillFrom)){//Overflow safe.
        memcpy(lFillFrom,pToFill,lFilledSoFar);
        lFillFrom+=lFilledSoFar;
        lFilledSoFar=lFilledSoFar<<1;//Doubling....
    }
    //No we can fill the endrestend of the buffer in one final step. Could be half the job.
    memcpy(lFillFrom,pToFill,pToFillSize-lFilledSoFar);
    return 0;
}

Can it be improvedbettered?

One use is to fill an array with a default structure. If If that is the purpose you don't need the initial fannying about with the short buffer special case.

I half remember one where it was 0xFFF...FF and that was clever because the hardware could detect overflow easily and handle all sorts of wrap-around errors gracefully. I'm damned if I can remember what it was. It may have been a hypothetical example to show why standards should give implementers freedom.

Versioning: This is V1.1 19-Dec-2014 including improvements suggested by @Edward - See answer below.

Making multiple copies of a pattern

#include <string.h> //This is where memcpy() hangs out. I know! I know!

///memcopyfill: Fills a block of memory with a specified pattern from the address pToFill for pToFillSize bytes.
///Will fill the whole buffer including a trailing partial pattern at the end (if necesssary).
///pFillWithSize must not be 0. pFillWith must not be NULL. 
///If Either pToFill is NULL or pToFillSize is 0, does nothing and returns without error.
///The area to fill and pattern must not overlap or behaviour is undefined.
///Returns 0 on success and non-zero on error.
int memcopyfill(void*const pToFill,const size_t pToFillSize,const void*const  pFillWith,const size_t pFillWithSize){
    if(pToFill==NULL||pToFillSize==0){
        return 0; //Nothing to do.
    }
    if(pFillWith==NULL||pFillWithSize==0){
        return 1; //ERROR! Something to fill and nothing to fill it with.
    }
    if(pToFillSize<=pFillWithSize){
        memcpy(pToFill,pFillWith,pToFillSize);
        return 0; //Short buffer.
    }
    //The to buffer is bigger so we start with a full copy of pattern.
    memcpy(pToFill,pFillWith,pFillWithSize);
    
    //Now we keep doubling the copies by copying and copying from the target onto itself.
    char*lFillFrom=((char*)pToFill)+pFillWithSize;
    size_t lFilledSoFar=pFillWithSize;
    char*lFillEnd=((char*)pToFill)+pToFillSize;
    while(lFilledSoFar<(lFillEnd-lFillFrom)){//Overflow safe.
        memcpy(lFillFrom,pToFill,lFilledSoFar);
        lFillFrom+=lFilledSoFar;
        lFilledSoFar=lFilledSoFar<<1;//Doubling....
    }
    //No we fill the endrest of the buffer. 
    memcpy(lFillFrom,pToFill,pToFillSize-lFilledSoFar);
    return 0;
}

Can it be improved?

One use is to fill an array with a default structure. If that is the purpose you don't need the initial fannying about with the short buffer special case.

I half remember one where it was 0xFFF...FF and that was clever because the hardware could detect overflow easily and handle all sorts of wrap-around errors gracefully. I'm damned if I can remember what it was. It may have been a hypothetical example to show why standards should give implementers freedom.

Versioning: This is V1.1 19-Dec-2014 including improvements suggested by @Edward - See answer below.

Making Multiple Copies of a Pattern

#include <string.h> //This is where memcpy() hangs out. I know! I know!

///Fills a block of memory with a specified pattern. 
///The target block starts at pToFill and extends for pToFillSize bytes.
///The source pattern starts at pFillWith and extends for pFillWithSize bytes.
///Will fill the whole buffer including a trailing partial pattern at the end (if necesssary).
///pFillWithSize must not be 0. pFillWith must not be NULL.
///If Either pToFill is NULL or pToFillSize is 0, does nothing and returns without error.
///The area to fill and pattern must not overlap or behaviour is undefined.
void memcopyfill(void*const pToFill,const size_t pToFillSize,void*const  pFillWith,const size_t pFillWithSize){
    if(pToFill==NULL||pToFillSize==0){
        return;//Nothing to do.
    }
    if(pFillWith==NULL||pFillWithSize==0){
        return;//Can do nothing...
    }
    if(pToFillSize<pFillWithSize){
        memcpy(pToFill,pFillWith,pToFillSize);
        return;//Short buffer.
    }
    //The to buffer is bigger so we start with a full copy of pattern.  
    //Now we keep doubling the copies by copying and copying from the target onto itself.
    char*lFillFrom=((char*)pToFill)+pFillWithSize;
    size_t lFilledSoFar=pFillWithSize;
    char*lFillEnd=((char*)pToFill)+pToFillSize;
    while(lFilledSoFar<(lFillEnd-lFillFrom)){//Overflow safe.
        memcpy(lFillFrom,pToFill,lFilledSoFar);
        lFillFrom+=lFilledSoFar;
        lFilledSoFar=lFilledSoFar<<1;//Doubling....
    }
    //No we can fill the end of the buffer in one final step. Could be half the job.
    memcpy(lFillFrom,pToFill,pToFillSize-lFilledSoFar);
}

Can it be bettered?

One use is to fill an array with a default structure. If that is the purpose you don't need the initial fannying about with the short buffer special case.

I half remember one where it was 0xFFF...FF and that was clever because the hardware could detect overflow easily and handle all sorts of wrap-around errors gracefully. I'm damned if I can remember what it was. It may have been a hypothetical example to show why standards should give implementers freedom.

Edited following feedback.
Source Link
user59064
user59064
Loading
deleted 5 characters in body; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237
Loading
added missing line of code
Source Link
Edward
  • 66.6k
  • 4
  • 118
  • 282
Loading
added 151 characters in body
Source Link
user59064
user59064
Loading
Source Link
user59064
user59064
Loading