www.pudn.com > M2Server.rar > EDcode.pas
////////////////////////////////////////////////////////////////////////////////
// //
// 工程: M2Server //
// 版本: 1.0 //
// 公司: 乐都在线 //
// 网址: http://www.hh8.net //
// 日期: 2005-05-28 //
// //
////////////////////////////////////////////////////////////////////////////////
unit EDcode;
interface
uses
Windows, SysUtils, Classes, ClassDeclaration;
function fnDecode6BitBufA(pszSrc, pszDest: PChar; nDestLen: Integer): Integer;
function Decode6BitBuf(source: string; buf: PChar; BufLen: Integer): Integer;
function Encode6BitBuf(src, Dest: PChar; SrcLen, destlen: Integer): Integer;
function EncodeMessage(sMsg: TDEFAULTMESSAGE_RCD): string;
function DecodeMessage(Str: string): TDEFAULTMESSAGE_RCD;
function EncodeString(Str: string): string;
function DecodeString(Str: string): string;
function EncodeBuffer(buf: PChar; bufsize: Integer): string;
procedure DecodeBuffer(src: string; buf: PChar; bufsize: Integer);
function MakeDefaultMsg(wIdent: Word; nRecog: Integer; wParam, wTag, wSeries:
Word): TDEFAULTMESSAGE_RCD;
var
CSEncode: TRTLCriticalSection;
const
code = $3C;
implementation
var
EncBuf, TempBuf: PChar;
function fnDecode6BitBufA(pszSrc, pszDest: PChar; nDestLen: Integer): Integer;
var
I,
nLen,
nDestPos,
nBitPos,
nMadeBit: Integer;
chCode,
chTemp,
tmp: Byte;
Decode6BitMask: array[0..4] of Char;
begin
nLen := StrLen(pszSrc);
nDestPos := 0;
nBitPos := 2;
nMadeBit := 0;
Decode6BitMask[0] := Char($FC);
Decode6BitMask[1] := Char($F8);
Decode6BitMask[2] := Char($F0);
Decode6BitMask[3] := Char($E0);
Decode6BitMask[4] := Char($C0);
for I := 0 to nLen - 1 do //Iterate
begin
if pszSrc[I] >= Char($3C) then
begin
chTemp := Byte(Integer(pszSrc[I]) - $3C);
end
else
begin
nDestPos := 0;
Break;
end;
if nDestPos >= nDestLen then
begin
Break;
end;
if nMadeBit >= 2 then
begin
chCode := Byte(Char(Integer(tmp) or ((Integer(chTemp) and ($3F)) shr (6 -
nBitPos))));
pszDest[nDestPos] := Char(chCode);
Inc(nDestPos);
nMadeBit := 0;
if nBitPos < 6 then
begin
Inc(nBitPos);
Inc(nBitPos);
end
else
begin
nBitPos := 2;
Continue;
end;
end;
tmp := Byte((Integer(chTemp) shl nBitPos) and (Integer(Decode6BitMask[nBitPos
- 2])));
nMadeBit := nMadeBit + 8 - nBitPos;
end;
pszDest[nDestPos] := #0;
Result := nDestPos;
end;
function MakeDefaultMsg(wIdent: Word; nRecog: Integer; wParam, wTag, wSeries:
Word): TDEFAULTMESSAGE_RCD;
begin
Result.nRecog := nRecog;
Result.wIdent := wIdent;
Result.wParam := wParam;
Result.wTag := wTag;
Result.wSeries := wSeries;
end;
function Encode6BitBuf(src, Dest: PChar; SrcLen, destlen: Integer): Integer;
var
I, restcount, destpos: Integer;
made, Ch, rest: Byte;
begin
try
restcount := 0;
rest := 0;
destpos := 0;
for I := 0 to SrcLen - 1 do
begin
if destpos >= destlen then
Break;
Ch := Byte(src[I]);
made := Byte((rest or (Ch shr (2 + restcount))) and $3F);
rest := Byte(((Ch shl (8 - (2 + restcount))) shr 2) and $3F);
Inc(restcount, 2);
if restcount < 6 then
begin
Dest[destpos] := Char(made + code);
Inc(destpos);
end
else
begin
if destpos < destlen - 1 then
begin
Dest[destpos] := Char(made + code);
Dest[destpos + 1] := Char(rest + code);
Inc(destpos, 2);
end
else
begin
Dest[destpos] := Char(made + code);
Inc(destpos);
end;
restcount := 0;
rest := 0;
end;
end;
if restcount > 0 then
begin
Dest[destpos] := Char(rest + code);
Inc(destpos);
end;
Dest[destpos] := #0;
finally
Result := destpos;
end;
end;
function Decode6BitBuf(source: string; buf: PChar; BufLen: Integer): Integer;
const
Masks: array[2..6] of Byte = ($FC, $F8, $F0, $E0, $C0);
//($FE, $FC, $F8, $F0, $E0, $C0, $80, $00);
var
I, len, bitpos, madebit, bufpos: Integer;
Ch, tmp, _byte: Byte;
begin
try
len := Length(source);
bitpos := 2;
madebit := 0;
bufpos := 0;
tmp := 0;
for I := 1 to len do
begin
if Integer(source[I]) - code >= 0 then
Ch := Byte(source[I]) - code
else
begin
bufpos := 0;
Break;
end;
if bufpos >= BufLen then
Break;
if (madebit + 6) >= 8 then
begin
_byte := Byte(tmp or ((Ch and $3F) shr (6 - bitpos)));
buf[bufpos] := Char(_byte);
Inc(bufpos);
madebit := 0;
if bitpos < 6 then
Inc(bitpos, 2)
else
begin
bitpos := 2;
Continue;
end;
end;
tmp := Byte(Byte(Ch shl bitpos) and Masks[bitpos]); // #### ##--
Inc(madebit, 8 - bitpos);
end;
buf[bufpos] := #0;
finally
Result := bufpos;
end;
end;
function DecodeMessage(Str: string): TDEFAULTMESSAGE_RCD;
var
msg: TDEFAULTMESSAGE_RCD;
begin
try
EnterCriticalSection(CSEncode);
Decode6BitBuf(Str, EncBuf, 1024);
Move(EncBuf^, msg, SizeOf(TDEFAULTMESSAGE_RCD));
Result := msg;
finally
LeaveCriticalSection(CSEncode);
end;
end;
function DecodeString(Str: string): string;
begin
try
EnterCriticalSection(CSEncode);
Decode6BitBuf(Str, EncBuf, 65536);
Result := Strpas(EncBuf); //error, 1, 2, 3,...
finally
LeaveCriticalSection(CSEncode);
end;
end;
procedure DecodeBuffer(src: string; buf: PChar; bufsize: Integer);
begin
try
EnterCriticalSection(CSEncode);
Decode6BitBuf(src, EncBuf, 65536);
Move(EncBuf^, buf^, bufsize);
finally
LeaveCriticalSection(CSEncode);
end;
end;
function EncodeMessage(sMsg: TDEFAULTMESSAGE_RCD): string;
begin
try
EnterCriticalSection(CSEncode);
Move(sMsg, TempBuf^, SizeOf(TDEFAULTMESSAGE_RCD));
Encode6BitBuf(TempBuf, EncBuf, SizeOf(TDEFAULTMESSAGE_RCD), 1024);
Result := Strpas(EncBuf); //Error: 1, 2, 3, 4, 5, 6, 7, 8, 9
finally
LeaveCriticalSection(CSEncode);
end;
end;
function EncodeString(Str: string): string;
begin
try
EnterCriticalSection(CSEncode);
Encode6BitBuf(PChar(Str), EncBuf, Length(Str), 65536);
Result := Strpas(EncBuf);
finally
LeaveCriticalSection(CSEncode);
end;
end;
function EncodeBuffer(buf: PChar; bufsize: Integer): string;
begin
try
EnterCriticalSection(CSEncode);
if bufsize < 65536 then
begin
Move(buf^, TempBuf^, bufsize);
Encode6BitBuf(TempBuf, EncBuf, bufsize, 65536);
Result := Strpas(EncBuf);
end
else
Result := '';
finally
LeaveCriticalSection(CSEncode);
end;
end;
initialization
begin
GetMem(EncBuf, 10240 + 100); //65536 + 100);
GetMem(TempBuf, 10240); //2048);
InitializeCriticalSection(CSEncode);
end;
finalization
begin
//FreeMem (EncBuf, BUFFERSIZE + 100);
//FreeMem (TempBuf, 2048);
DeleteCriticalSection(CSEncode);
end;
end.