Ive been working at this for the past day and its driving me wild. Basically, all this code is supposed to do is to take an array of binary data, replace all occurances of 0xff (what I call a 'set byte') with some two-byte value (called the 'expand word'), then restore the array to its original form. The two-byte value is determined by finding a two-byte sequence that is _not_ in the array. This code seems to fail about 1 out of 10 times for reasons unknown. The main function is used to test the functions 'ExpandSetByteInBuffer' and 'RestoreSetByteInBuffer'. The other functions are used within these two. Ive included comments at key areas. Any help will be much appreciated. Oh yeah, by the way, this code is (c) *ClownPimp*
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
typedef unsigned short USHORT;
typedef unsigned char UCHAR;
typedef unsigned int UINT;
typedef unsigned long ULONG;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
#define SET_BYTE_EXP_SIZE 2
/* generates the two byte sequence by recording all two-byte sequences in the array an picking one from the remaining sequences */
WORD GenerateExpandWord(BYTE buffer[], UINT bufsize)
{
BYTE *p1 = buffer, *p2 = buffer+1;
UCHAR table[256][256] = {0}; // buffer has a max value of
// about 10000, so there must
// be an unused byte-sequence
for (UINT i = 1; i < bufsize; i++)
table[*p1++][*p2++] = 1; // record all the byte sequences
for (UINT j = 0; j < 255; j++)
{
for (i = 0; i < 255; i++)
{
if (table[j][i] == 0) // choose the first unused sequence
return (j << 8) | i;
}
}
return (WORD)0; // should never reach here
}
/* crap, moms gotta use the comp, Ill come back and add some more comments later (maybe, the code shouldnt be to hard to figure out) */
UINT FindNumSetBytes(BYTE *buf, UINT bufsize)
{
UINT k = 0;
for (UINT i = 0; i < bufsize; i++)
if (*buf++ == 0xff) k++;
return k;
}
USHORT RestoreSetByteInBuffer(BYTE buffer[], UINT buf_bytes, WORD expandWord)
{
BYTE *temp_buf, *tbp, *bp = buffer, expWdH, expWdL;
USHORT k = 0;
expWdH = BYTE(expandWord >> 8); // the high byte
expWdL = BYTE(expandWord & 0x00ff); // the low byte
temp_buf = tbp = new BYTE[buf_bytes];
for (UINT i = 0; i < buf_bytes; i++)
{
if (*bp == expWdH &&
*(bp+1) == expWdL)
{
*tbp++ = 0xff;
bp += 2;
i++;
}
else
{
*tbp++ = *bp++;
}
}
k = tbp - temp_buf;
memcpy(buffer, temp_buf, k);
delete[] temp_buf;
return k;
}
USHORT ExpandSetByteInBuffer(BYTE buffer[], UINT bufsize, WORD *expandWord)
{
BYTE *temp_buf, *tbp, *bp = buffer, expWdH, expWdL;
USHORT expSize;
*expandWord = GenerateExpandWord(buffer, bufsize);
expWdH = BYTE(*expandWord >> 8);
expWdL = BYTE(*expandWord & 0x00ff);
expSize = bufsize + (SET_BYTE_EXP_SIZE - 1) * FindNumSetBytes(buffer, bufsize);
temp_buf = tbp = new BYTE[expSize];
for (UINT i = 0; i < bufsize; i++)
{
if (*bp == 0xff)
{
*tbp++ = expWdH;
*tbp++ = expWdL;
bp++;
}
else
{
*tbp++ = *bp++;
}
}
memcpy(buffer, temp_buf, expSize);
delete[] temp_buf;
return expSize;
}
int main(int argc, char *argv[])
{
srand(time(NULL));
BYTE buffer[10000], b[5000];
WORD blockSize, expandWord;
for(UINT j = 0; j < 500; j++)
{
for (UINT i = 0; i < 5000; i++)
b[i] = buffer[i] = (rand() % 256);
blockSize = ExpandSetByteInBuffer(buffer, 5000, &expandWord);
blockSize = RestoreSetByteInBuffer(buffer, blockSize, expandWord);
if (memcmp(b, buffer, blockSize) == 0 && blockSize == 5000)
puts("SUCCESS!");
else
puts("FAILURE"); // add breakpoint here
}
return 0;
}