我把一个C写的解压文件的一些函数改写成Delphi的函数,编译没问题,但结果没达到理想.我基本是一行行的改写的,但对于C的指针我不是很了解,不明白具体错在哪儿,调试了N次仍不得要领,想请教论坛里高手,帮我看看问题所在.
(我在Delphi 2010下编译)
附:C的代码及我改写的Delphi代码,省略了一些不影响读的部分
#define RNC_FILE_IS_NOT_RNC -1
#define RNC_HUF_DECODE_ERROR -2
#define RNC_FILE_SIZE_MISMATCH -3
#define RNC_PACKED_CRC_ERROR -4
#define RNC_UNPACKED_CRC_ERROR -5
#define RNC_HEADER_VAL_ERROR -6
#define RNC_HUF_EXCEEDS_RANGE -7
#define RNC_SIGNATURE 0x524E4301 /* "RNC\001" */typedef struct {
unsigned long bitbuf;
int bitcount;
} bit_stream;typedef struct {
int num;
struct {
unsigned long code;
int codelen;
int value;
} table[32];
} huf_table;long rnc_unpack (void *packed, void *unpacked)
{
unsigned char *input = packed;
unsigned char *output = unpacked;
unsigned char *inputend, *outputend;
bit_stream bs;
huf_table raw, dist, len;
unsigned long ch_count;
unsigned long ret_len, inp_len; if (blong(input) != RNC_SIGNATURE)
return RNC_HEADER_VAL_ERROR;
ret_len = blong (input+4);
inp_len = blong (input+8);
input += 18;
outputend = output + ret_len;
inputend = input + inp_len;
bitread_init (&bs, &input, inputend);
bit_advance (&bs, 2, &input, inputend);
while (output < outputend)
{
if (inputend-input<6)
return RNC_HUF_EXCEEDS_RANGE;
read_huftable (&raw, &bs, &input, inputend);
read_huftable (&dist, &bs, &input, inputend);
read_huftable (&len, &bs, &input, inputend);
ch_count = bit_read (&bs, 0xFFFF, 16, &input, inputend);
while (1)
{
long length, posn;
length = huf_read (&raw, &bs, &input,inputend);
if (length < 0)
return RNC_HUF_DECODE_ERROR;
if (length)
{
while (length--)
{
if ((input>=inputend)||(output>=outputend))
return RNC_HUF_EXCEEDS_RANGE;
*output++ = *input++;
}
bitread_fix (&bs, &input, inputend);
}
if (--ch_count <= 0)
break;
posn = huf_read (&dist, &bs, &input,inputend);
if (posn == -1)
return RNC_HUF_DECODE_ERROR;
length = huf_read (&len, &bs, &input,inputend);
if (length < 0)
return RNC_HUF_DECODE_ERROR;
posn += 1;
length += 2;
while (length--)
{
if ((((void *)output-posn)<unpacked)||((output-posn)>outputend)||
(((void *)output)<unpacked)||((output)>outputend))
return RNC_HUF_EXCEEDS_RANGE;
*output = output[-posn];
output++;
}
}
}
if (outputend != output)
{
if (!(flags&RNC_IGNORE_FILE_SIZE_MISMATCH))
return RNC_FILE_SIZE_MISMATCH;
}
return ret_len;
}static void read_huftable (huf_table *h, bit_stream *bs, unsigned char **p, unsigned char *pend)
{
int i, j, k, num;
int leaflen[32];
int leafmax;
unsigned long codeb; num = bit_read (bs, 0x1F, 5, p, pend);
if (!num)
return;
leafmax = 1;
for (i=0; i<num; i++)
{
leaflen[i] = bit_read (bs, 0x0F, 4, p, pend);
if (leafmax < leaflen[i])
leafmax = leaflen[i];
}
codeb = 0L;
k = 0;
for (i=1; i<=leafmax; i++)
{
for (j=0; j<num; j++)
if (leaflen[j] == i)
{
h->table[k].code = mirror (codeb, i);
h->table[k].codelen = i;
h->table[k].value = j;
codeb++;
k++;
}
codeb <<= 1;
}
h->num = k;
}static unsigned long huf_read (huf_table *h, bit_stream *bs, unsigned char **p,unsigned char *pend)
{
int i;
unsigned long val; for (i=0; i<h->num; i++)
{
unsigned long mask = (1 << h->table[i].codelen) - 1;
if (bit_peek(bs, mask) == h->table[i].code)
break;
}
if (i == h->num)
return -1;
bit_advance (bs, h->table[i].codelen, p, pend);
val = h->table[i].value;
if (val >= 2)
{
val = 1 << (val-1);
val |= bit_read (bs, val-1, h->table[i].value - 1, p, pend);
}
return val;
}static void bitread_init (bit_stream *bs, unsigned char **p, unsigned char *pend)
{
if (pend-(*p) >= 0)
bs->bitbuf = lword (*p);
else
bs->bitbuf = 0;
bs->bitcount = 16;
}static void bitread_fix (bit_stream *bs, unsigned char **p, unsigned char *pend)
{
bs->bitcount -= 16;
bs->bitbuf &= (1<<bs->bitcount)-1;
if (pend-(*p) >= 0)
bs->bitbuf |= (lword(*p)<<bs->bitcount);
bs->bitcount += 16;
}static unsigned long bit_peek (bit_stream *bs, unsigned long mask)
{
return bs->bitbuf & mask;
}static void bit_advance (bit_stream *bs, int n, unsigned char **p, unsigned char *pend)
{
bs->bitbuf >>= n;
bs->bitcount -= n;
if (bs->bitcount < 16)
{
(*p) += 2;
if (pend-(*p) >= 0)
bs->bitbuf |= (lword(*p)<<bs->bitcount);
bs->bitcount += 16;
}
}static unsigned long bit_read (bit_stream *bs, unsigned long mask,int n, unsigned char **p, unsigned char *pend)
{
unsigned long result = bit_peek (bs, mask);
bit_advance (bs, n, p, pend);
return result;
}static unsigned long mirror (unsigned long x, int n)
{
unsigned long top = 1 << (n-1), bottom = 1;
while (top > bottom)
{
unsigned long mask = top | bottom;
unsigned long masked = x & mask;
if (masked != 0 && masked != mask)
x ^= mask;
top >>= 1;
bottom <<= 1;
}
return x;
}static unsigned long blong (unsigned char *p)
{
unsigned long n;
n = p[0];
n = (n << 8) + p[1];
n = (n << 8) + p[2];
n = (n << 8) + p[3];
return n;
}static unsigned long llong (unsigned char *p)
{
unsigned long n;
n = p[3];
n = (n << 8) + p[2];
n = (n << 8) + p[1];
n = (n << 8) + p[0];
return n;
}static unsigned long bword (unsigned char *p)
{
unsigned long n;
n = p[0];
n = (n << 8) + p[1];
return n;
}static unsigned long lword (unsigned char *p)
{
unsigned long n;
n = p[1];
n = (n << 8) + p[0];
return n;
}
(我在Delphi 2010下编译)
附:C的代码及我改写的Delphi代码,省略了一些不影响读的部分
#define RNC_FILE_IS_NOT_RNC -1
#define RNC_HUF_DECODE_ERROR -2
#define RNC_FILE_SIZE_MISMATCH -3
#define RNC_PACKED_CRC_ERROR -4
#define RNC_UNPACKED_CRC_ERROR -5
#define RNC_HEADER_VAL_ERROR -6
#define RNC_HUF_EXCEEDS_RANGE -7
#define RNC_SIGNATURE 0x524E4301 /* "RNC\001" */typedef struct {
unsigned long bitbuf;
int bitcount;
} bit_stream;typedef struct {
int num;
struct {
unsigned long code;
int codelen;
int value;
} table[32];
} huf_table;long rnc_unpack (void *packed, void *unpacked)
{
unsigned char *input = packed;
unsigned char *output = unpacked;
unsigned char *inputend, *outputend;
bit_stream bs;
huf_table raw, dist, len;
unsigned long ch_count;
unsigned long ret_len, inp_len; if (blong(input) != RNC_SIGNATURE)
return RNC_HEADER_VAL_ERROR;
ret_len = blong (input+4);
inp_len = blong (input+8);
input += 18;
outputend = output + ret_len;
inputend = input + inp_len;
bitread_init (&bs, &input, inputend);
bit_advance (&bs, 2, &input, inputend);
while (output < outputend)
{
if (inputend-input<6)
return RNC_HUF_EXCEEDS_RANGE;
read_huftable (&raw, &bs, &input, inputend);
read_huftable (&dist, &bs, &input, inputend);
read_huftable (&len, &bs, &input, inputend);
ch_count = bit_read (&bs, 0xFFFF, 16, &input, inputend);
while (1)
{
long length, posn;
length = huf_read (&raw, &bs, &input,inputend);
if (length < 0)
return RNC_HUF_DECODE_ERROR;
if (length)
{
while (length--)
{
if ((input>=inputend)||(output>=outputend))
return RNC_HUF_EXCEEDS_RANGE;
*output++ = *input++;
}
bitread_fix (&bs, &input, inputend);
}
if (--ch_count <= 0)
break;
posn = huf_read (&dist, &bs, &input,inputend);
if (posn == -1)
return RNC_HUF_DECODE_ERROR;
length = huf_read (&len, &bs, &input,inputend);
if (length < 0)
return RNC_HUF_DECODE_ERROR;
posn += 1;
length += 2;
while (length--)
{
if ((((void *)output-posn)<unpacked)||((output-posn)>outputend)||
(((void *)output)<unpacked)||((output)>outputend))
return RNC_HUF_EXCEEDS_RANGE;
*output = output[-posn];
output++;
}
}
}
if (outputend != output)
{
if (!(flags&RNC_IGNORE_FILE_SIZE_MISMATCH))
return RNC_FILE_SIZE_MISMATCH;
}
return ret_len;
}static void read_huftable (huf_table *h, bit_stream *bs, unsigned char **p, unsigned char *pend)
{
int i, j, k, num;
int leaflen[32];
int leafmax;
unsigned long codeb; num = bit_read (bs, 0x1F, 5, p, pend);
if (!num)
return;
leafmax = 1;
for (i=0; i<num; i++)
{
leaflen[i] = bit_read (bs, 0x0F, 4, p, pend);
if (leafmax < leaflen[i])
leafmax = leaflen[i];
}
codeb = 0L;
k = 0;
for (i=1; i<=leafmax; i++)
{
for (j=0; j<num; j++)
if (leaflen[j] == i)
{
h->table[k].code = mirror (codeb, i);
h->table[k].codelen = i;
h->table[k].value = j;
codeb++;
k++;
}
codeb <<= 1;
}
h->num = k;
}static unsigned long huf_read (huf_table *h, bit_stream *bs, unsigned char **p,unsigned char *pend)
{
int i;
unsigned long val; for (i=0; i<h->num; i++)
{
unsigned long mask = (1 << h->table[i].codelen) - 1;
if (bit_peek(bs, mask) == h->table[i].code)
break;
}
if (i == h->num)
return -1;
bit_advance (bs, h->table[i].codelen, p, pend);
val = h->table[i].value;
if (val >= 2)
{
val = 1 << (val-1);
val |= bit_read (bs, val-1, h->table[i].value - 1, p, pend);
}
return val;
}static void bitread_init (bit_stream *bs, unsigned char **p, unsigned char *pend)
{
if (pend-(*p) >= 0)
bs->bitbuf = lword (*p);
else
bs->bitbuf = 0;
bs->bitcount = 16;
}static void bitread_fix (bit_stream *bs, unsigned char **p, unsigned char *pend)
{
bs->bitcount -= 16;
bs->bitbuf &= (1<<bs->bitcount)-1;
if (pend-(*p) >= 0)
bs->bitbuf |= (lword(*p)<<bs->bitcount);
bs->bitcount += 16;
}static unsigned long bit_peek (bit_stream *bs, unsigned long mask)
{
return bs->bitbuf & mask;
}static void bit_advance (bit_stream *bs, int n, unsigned char **p, unsigned char *pend)
{
bs->bitbuf >>= n;
bs->bitcount -= n;
if (bs->bitcount < 16)
{
(*p) += 2;
if (pend-(*p) >= 0)
bs->bitbuf |= (lword(*p)<<bs->bitcount);
bs->bitcount += 16;
}
}static unsigned long bit_read (bit_stream *bs, unsigned long mask,int n, unsigned char **p, unsigned char *pend)
{
unsigned long result = bit_peek (bs, mask);
bit_advance (bs, n, p, pend);
return result;
}static unsigned long mirror (unsigned long x, int n)
{
unsigned long top = 1 << (n-1), bottom = 1;
while (top > bottom)
{
unsigned long mask = top | bottom;
unsigned long masked = x & mask;
if (masked != 0 && masked != mask)
x ^= mask;
top >>= 1;
bottom <<= 1;
}
return x;
}static unsigned long blong (unsigned char *p)
{
unsigned long n;
n = p[0];
n = (n << 8) + p[1];
n = (n << 8) + p[2];
n = (n << 8) + p[3];
return n;
}static unsigned long llong (unsigned char *p)
{
unsigned long n;
n = p[3];
n = (n << 8) + p[2];
n = (n << 8) + p[1];
n = (n << 8) + p[0];
return n;
}static unsigned long bword (unsigned char *p)
{
unsigned long n;
n = p[0];
n = (n << 8) + p[1];
return n;
}static unsigned long lword (unsigned char *p)
{
unsigned long n;
n = p[1];
n = (n << 8) + p[0];
return n;
}
const
RNC_FILE_IS_NOT_RNC =-1;
RNC_HUF_DECODE_ERROR =-2;
RNC_FILE_SIZE_MISMATCH =-3;
RNC_PACKED_CRC_ERROR =-4;
RNC_UNPACKED_CRC_ERROR =-5;
RNC_HEADER_VAL_ERROR =-6;
RNC_HUF_EXCEEDS_RANGE =-7;
RNC_SIGNATURE =$524E4301;
type
PByte=^Byte;
bit_stream=record
bitbuf:longword;
bitcount:integer;
end;
huf_table=record
num:integer;
table:array [0..31] of
record
code:longword;
codelen:integer;
value:integer;
end;
end;implementationfunction rnc_unpack (var _packed, unpacked:TMemoryStream):longint;
var
inPos,outPos,inEnd,outEnd,tp:PByte;
bs:bit_stream;
raw, dist, len:huf_table;
ch_count:longword;
ret_len, inp_len:longword;
length, posn:longint;
begin
inPos:=PByte(_packed.Memory);
if (blong(inPos) <> RNC_SIGNATURE) then
begin
Result:=RNC_HEADER_VAL_ERROR;
exit;
end;
inc(inPos,4);
ret_len := blong(inPos);
inc(inPos,4);
inp_len := blong(inPos);
inc(inPos,10);
unpacked.SetSize(ret_len);
outPos:=PByte(unpacked.Memory);
outEnd := outPos;
inc(outEnd, ret_len);
inEnd := inPos;
inc(inEnd, inp_len);
bitread_init (bs, inPos, inEnd);
bit_advance (bs, 2, inPos, inEnd);
while (longword(@outPos) < longword(@outEnd)) do
begin
if longword(@InEnd)-longword(@inPos)<6 then
begin
Result:=RNC_HUF_EXCEEDS_RANGE;
exit;
end;
read_huftable (raw, bs, inPos, inEnd);
read_huftable (dist, bs, inPos, inEnd);
read_huftable (len, bs, inPos, inEnd);
ch_count := bit_read (bs, $FFFF, 16, inPos, inEnd);
while (True) do
begin
length := huf_read (raw, bs, inPos, inEnd);
if (length < 0) then
begin
Result:=RNC_HUF_DECODE_ERROR;
exit;
end;
if (length>0) then
begin
while (length>0) do
begin
outPos^:=inPos^;
inc(outPos);
inc(inPos); dec(length);
end;
bitread_fix (bs, inPos, inEnd);
end;
dec(ch_count);
if (ch_count <= 0) then
break;
posn := huf_read (dist, bs, inPos, inEnd);
if (posn = -1) then
begin
Result:=RNC_HUF_DECODE_ERROR;
exit;
end;
length := huf_read (len, bs, inPos, inEnd);
if (length < 0) then
begin
Result:=RNC_HUF_DECODE_ERROR;
exit;
end;
inc(posn);
inc(length,2);
while (length>0) do
begin
if (((longword(@output)-posn)<longword(@unpacked.Memory))
or ((longword(@output)-posn)>longword(@outEnd))
or (longword(@output)<longword(@unpacked.Memory))
or (longword(@output)>longword(@outEnd))) then
begin
Result:=RNC_HUF_EXCEEDS_RANGE;
exit;
end;
tp:=outPos;
dec(tp,posn);
outPos^:=tp^; inc(outPos);
dec(length);
end;
end;
end;
if (longword(@outPos) <> longword(@outEnd)) then
begin
Result:=RNC_FILE_SIZE_MISMATCH;
exit;
end;
Result:=ret_len;
end;procedure read_huftable (var h:huf_table;var bs:bit_stream;var p,pend:PByte);
var
i, j, k, num:integer;
leaflen:array [0..31] of integer;
leafmax:integer;
codeb:longword;
begin
num := bit_read (bs, $1F, 5, p, pend);
if (num=0) then
exit;
leafmax := 1;
for i:=0 to num-1 do
begin
leaflen[i] := bit_read (bs, $0F, 4, p, pend);
if (leafmax < leaflen[i]) then
leafmax := leaflen[i];
end;
codeb := 0;
k := 0;
for i:=1 to leafmax do
begin
for j:=0 to num-1 do
if (leaflen[j] = i) then
begin
h.table[k].code := mirror (codeb, i);
h.table[k].codelen := i;
h.table[k].value := j;
inc(codeb);
inc(k);
end;
codeb := codeb shl 1;
end;
h.num := k;
end;function huf_read (var h:huf_table;var bs:bit_stream;var p,pend:PByte):longint;
var
i:integer;
val,mask:longword;
begin
for i:=0 to h.num-1 do
begin
mask := (1 shl h.table[i].codelen) - 1;
if (bit_peek(bs, mask) = h.table[i].code) then
break;
end;
if (i = h.num) then
begin
Result:=-1;
exit;
end;
bit_advance (bs, h.table[i].codelen, p, pend);
val := h.table[i].value;
if (val >= 2) then
begin
val := 1 shl (val-1);
val :=val or (bit_read (bs, val-1, h.table[i].value - 1, p, pend));
end;
Result:=val;
end;procedure bitread_init (var bs:bit_stream;var p,pend:PByte);
begin
if (longword(@pend)-longword(@p))>=0 then
bs.bitbuf := lword(p)
else
bs.bitbuf:=0;
bs.bitcount := 16;
end;procedure bitread_fix (var bs:bit_stream;var p,pend:PByte);
begin
bs.bitcount := bs.bitcount - 16;
bs.bitbuf := bs.bitbuf and ((1 shl bs.bitcount)-1);
if (longword(@pend)-longword(@p))>=0 then
bs.bitbuf := bs.bitbuf or (lword( p ) shl bs.bitcount);
bs.bitcount := bs.bitcount + 16;
end;function bit_peek (var bs:bit_stream; mask:longword):longword;
begin
Result:=bs.bitbuf and mask;
end;procedure bit_advance (var bs:bit_stream; n:integer;var p,pend:PByte);
begin
bs.bitbuf:=bs.bitbuf shr n;
bs.bitcount:=bs.bitcount - n;
if (bs.bitcount < 16) then
begin
inc(p,2);
if (longword(@pend)-longword(@p))>=0 then
bs.bitbuf := bs.bitbuf or (lword( p ) shl bs.bitcount);
bs.bitcount := bs.bitcount + 16;
end;
end;function bit_read (var bs:bit_stream; mask:longword; n:integer;var p,pend:PByte):longword;
begin
Result := bit_peek (bs, mask);
bit_advance (bs, n, p, pend);
end;function mirror(x:longword; n:integer):longword;
var
top,bottom,mask,masked:longword;
begin
top := 1 shl (n-1);
bottom := 1;
while (top > bottom) do
begin
mask := top or bottom;
masked := x and mask;
if ((masked <> 0) and (masked <> mask)) then
x :=x xor mask;
top :=top shr 1;
bottom :=bottom shl 1;
end;
Result:=x;
end;function bword(pb:PByte):word;
var
b1,b2:byte;
begin
b1:=pb^;
inc(pb);
b2:=pb^;
result:=(word(b1) shl 8) or word(b2);
end;function lword(pb:PByte):word;
var
b1,b2:byte;
begin
b2:=pb^;
inc(pb);
b1:=pb^;
result:=(word(b1) shl 8) or word(b2);
end;function blong(pb:PByte):longword;
var
b:array [0..3] of byte;
i:integer;
begin
for i := 0 to 3 do
begin
b[i]:=pb^;
inc(pb);
end;
Result:=(longword(b[0]) shl 24) or (longword(b[1]) shl 16)
or (longword(b[2]) shl 8) or longword(b[3]);
end;function llong(pb:PByte):longword;
var
b:array [0..3] of byte;
i:integer;
begin
for i := 3 downto 0 do
begin
b[i]:=pb^;
inc(pb);
end;
Result:=(longword(b[0]) shl 24) or (longword(b[1]) shl 16)
or (longword(b[2]) shl 8) or longword(b[3]);
end;end.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;type test1= record
a: byte;
b: byte;
c: integer;
end;type test2= packed record
a: byte;
b: byte;
c: integer;
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
t1: test1;
t2: test2;
begin
showmessage(IntToStr(sizeof(t1)));
showmessage(IntToStr(sizeof(t2)));
end;end.