NM64Encode.pas
上传用户:szzdds
上传日期:2013-09-18
资源大小:293k
文件大小:4k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit NM64Encode;
  2. interface
  3. uses
  4.   Classes;
  5. function B64Encode(const source, destination: TStream): Boolean;
  6. implementation
  7. uses
  8.   NMFileBuffer;
  9. var
  10.   B64Table: array[0..63] of Char =
  11.   ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
  12.     'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  13.     'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
  14.     'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  15.     'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  16.     'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  17.     'w', 'x', 'y', 'z', '0', '1', '2', '3',
  18.     '4', '5', '6', '7', '8', '9', '+', '/');
  19. function B64Encode(const source, destination: TStream): Boolean;
  20. var
  21.   Counter: LongInt;
  22.   TotalBytes: LongInt;
  23.   EOD: Char;
  24.   B64Char: Char;
  25.   Char1: Char;
  26.   Char2: Char;
  27.   Char3: Char;
  28.   InputPtr, OutputPtr, BufferEnd: PChar;
  29.   MemStuff: TNMFileBuffer;
  30.   Output: string;
  31.   Len: Integer;
  32. begin
  33.   Counter := 0;
  34.   TotalBytes := source.Size;
  35.   EOD := '=';
  36.   Len := 62;
  37.   Output := '';
  38.   SetLength(Output, Len);
  39.   OutputPtr := PChar(Output);
  40.   destination.Seek(0, soFromEnd);
  41.   MemStuff := TNMFileBuffer.Create(source);
  42.   try
  43.     InputPtr := MemStuff.BufPos;
  44.     BufferEnd := MemStuff.BufEnd;
  45.     while True do
  46.     begin
  47.       if InputPtr >= BufferEnd then
  48.         if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
  49.           Break
  50.         else
  51.         begin
  52.           InputPtr := MemStuff.BufPos;
  53.           BufferEnd := MemStuff.BufEnd;
  54.         end;
  55.       Char1 := InputPtr^;
  56.       inc(InputPtr);
  57.       B64Char := B64Table[Byte(Char1) shr 2];
  58.       OutputPtr^ := B64Char;
  59.       inc(OutputPtr);
  60.       inc(Counter);
  61.       if Counter >= TotalBytes then
  62.       begin
  63.         Char2 := #0;
  64.         B64Char := B64Table[(((Byte(Char1) and $03) shl 4) or ((Byte(Char2) and $F0) shr 4))];
  65.         OutputPtr^ := B64Char;
  66.         inc(OutputPtr);
  67.         OutputPtr^ := EOD;
  68.         inc(OutputPtr);
  69.         OutputPtr^ := EOD;
  70.         inc(OutputPtr);
  71.       end
  72.       else
  73.       begin
  74.         if InputPtr >= BufferEnd then
  75.           if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
  76.             Break
  77.           else
  78.           begin
  79.             InputPtr := MemStuff.BufPos;
  80.             BufferEnd := MemStuff.BufEnd;
  81.           end;
  82.         Char2 := InputPtr^;
  83.         inc(InputPtr);
  84.         B64Char := B64Table[(((Byte(Char1) and $03) shl 4) or ((Byte(Char2) and $F0) shr 4))];
  85.         OutputPtr^ := B64Char;
  86.         inc(OutputPtr);
  87.         inc(Counter);
  88.         if Counter >= TotalBytes then
  89.         begin
  90.           Char3 := #0;
  91.           B64Char := B64Table[(((Byte(Char2) and $0F) shl 2) or ((Byte(Char3) and $C0) shr 6))];
  92.           OutputPtr^ := B64Char;
  93.           inc(OutputPtr);
  94.           OutputPtr^ := EOD;
  95.           inc(OutputPtr);
  96.         end
  97.         else
  98.         begin
  99.           if InputPtr >= BufferEnd then
  100.             if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
  101.               Break
  102.             else
  103.             begin
  104.               InputPtr := MemStuff.BufPos;
  105.               BufferEnd := MemStuff.BufEnd;
  106.             end;
  107.           Char3 := InputPtr^;
  108.           inc(InputPtr);
  109.           B64Char := B64Table[(((Byte(Char2) and $0F) shl 2) or ((Byte(Char3) and $C0) shr 6))];
  110.           OutputPtr^ := B64Char;
  111.           inc(OutputPtr);
  112.           inc(Counter);
  113.           B64Char := B64Table[(Byte(Char3) and $3F)];
  114.           OutputPtr^ := B64Char;
  115.           inc(OutputPtr);
  116.         end;
  117.       end;
  118.       if (Counter mod 45 = 0) or ((OutputPtr - 1)^ = EOD) then
  119.       begin
  120.         if ((OutputPtr - 1)^ <> EOD) then
  121.         begin
  122.           OutputPtr^ := #13;
  123.           inc(OutputPtr);
  124.           OutputPtr^ := #10;
  125.           inc(OutputPtr);
  126.           OutputPtr^ := #0;
  127.         end
  128.         else
  129.         begin
  130.           Len := LongInt(OutputPtr) - LongInt(Output);
  131.           SetLength(Output, Len);
  132.         end;
  133.         destination.Write(PChar(Output)^, Len);
  134.         OutputPtr := PChar(Output);
  135.       end;
  136.     end;
  137.   finally
  138.     MemStuff.Free;
  139.   end;
  140.   Len := LongInt(OutputPtr) - LongInt(Output);
  141.   if Len > 0 then
  142.   begin
  143.     SetLength(Output, Len);
  144.     destination.Write(PChar(Output)^, Len);
  145.   end;
  146.   destination.Write(EOD, 1);
  147.   result := True;
  148. end;
  149. end.