IdCoderMIME.pas 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. {
  2. $Project$
  3. $Workfile$
  4. $Revision$
  5. $DateUTC$
  6. $Id$
  7. This file is part of the Indy (Internet Direct) project, and is offered
  8. under the dual-licensing agreement described on the Indy website.
  9. (http://www.indyproject.org/)
  10. Copyright:
  11. (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
  12. }
  13. {
  14. $Log$
  15. }
  16. {
  17. Rev 1.3 26/03/2005 19:19:30 CCostelloe
  18. Fixes for "uneven size" exception
  19. Rev 1.2 2004.01.21 1:04:54 PM czhower
  20. InitComponenet
  21. Rev 1.1 10/6/2003 5:37:02 PM SGrobety
  22. Bug fix in decoders.
  23. Rev 1.0 11/14/2002 02:14:54 PM JPMugaas
  24. }
  25. unit IdCoderMIME;
  26. interface
  27. {$i IdCompilerDefines.inc}
  28. uses
  29. Classes,
  30. IdCoder3to4,
  31. IdGlobal;
  32. type
  33. TIdEncoderMIME = class(TIdEncoder3to4)
  34. protected
  35. procedure InitComponent; override;
  36. {$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
  37. public
  38. constructor Create(AOwner: TComponent); reintroduce; overload;
  39. {$ENDIF}
  40. end;
  41. TIdDecoderMIME = class(TIdDecoder4to3)
  42. protected
  43. procedure InitComponent; override;
  44. {$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
  45. public
  46. constructor Create(AOwner: TComponent); reintroduce; overload;
  47. {$ENDIF}
  48. end;
  49. {WARNING: This is not a general-purpose decoder. It is used, for example, by
  50. IdMessageCoderMIME for line-by-line decoding of base64 encoded parts that are
  51. processed on a line-by-line basis, as against the complete encoded block.}
  52. TIdDecoderMIMELineByLine = class(TIdDecoderMIME)
  53. protected
  54. FLeftFromLastTime: TIdBytes;
  55. public
  56. procedure DecodeBegin(ADestStream: TStream); override;
  57. procedure DecodeEnd; override;
  58. procedure Decode(ASrcStream: TStream; const ABytes: Integer = -1); override;
  59. end;
  60. const
  61. GBase64CodeTable: string =
  62. 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; {Do not Localize}
  63. var
  64. GBase64DecodeTable: TIdDecodeTable;
  65. implementation
  66. uses
  67. SysUtils;
  68. { TIdDecoderMIMELineByLine }
  69. procedure TIdDecoderMIMELineByLine.DecodeBegin(ADestStream: TStream);
  70. begin
  71. inherited DecodeBegin(ADestStream);
  72. {Clear out any bytes that may be left from a previous decode...}
  73. SetLength(FLeftFromLastTime, 0);
  74. end;
  75. procedure TIdDecoderMIMELineByLine.DecodeEnd;
  76. var
  77. LStream: TMemoryStream;
  78. LPos: Integer;
  79. begin
  80. if Length(FLeftFromLastTime) > 0 then begin
  81. LPos := Length(FLeftFromLastTime);
  82. SetLength(FLeftFromLastTime, 4);
  83. while LPos < 4 do begin
  84. FLeftFromLastTime[LPos] := Ord(FFillChar);
  85. Inc(LPos);
  86. end;
  87. LStream := TMemoryStream.Create;
  88. try
  89. WriteTIdBytesToStream(LStream, FLeftFromLastTime);
  90. LStream.Position := 0;
  91. inherited Decode(LStream);
  92. finally
  93. FreeAndNil(LStream);
  94. SetLength(FLeftFromLastTime, 0);
  95. end;
  96. end;
  97. inherited DecodeEnd;
  98. end;
  99. procedure TIdDecoderMIMELineByLine.Decode(ASrcStream: TStream; const ABytes: Integer = -1);
  100. var
  101. LMod, LDiv: integer;
  102. LIn, LSrc: TIdBytes;
  103. LStream: TMemoryStream;
  104. begin
  105. LIn := FLeftFromLastTime;
  106. if ReadTIdBytesFromStream(ASrcStream, LSrc, ABytes) > 0 then begin
  107. AppendBytes(LIn, LSrc);
  108. end;
  109. LMod := Length(LIn) mod 4;
  110. if LMod <> 0 then begin
  111. LDiv := (Length(LIn) div 4) * 4;
  112. FLeftFromLastTime := Copy(LIn, LDiv, Length(LIn)-LDiv);
  113. LIn := Copy(LIn, 0, LDiv);
  114. end else begin
  115. SetLength(FLeftFromLastTime, 0);
  116. end;
  117. LStream := TMemoryStream.Create;
  118. try
  119. WriteTIdBytesToStream(LStream, LIn);
  120. LStream.Position := 0;
  121. inherited Decode(LStream, ABytes);
  122. finally
  123. FreeAndNil(LStream);
  124. end;
  125. end;
  126. { TIdDecoderMIME }
  127. {$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
  128. constructor TIdDecoderMIME.Create(AOwner: TComponent);
  129. begin
  130. inherited Create(AOwner);
  131. end;
  132. {$ENDIF}
  133. procedure TIdDecoderMIME.InitComponent;
  134. begin
  135. inherited InitComponent;
  136. FDecodeTable := GBase64DecodeTable;
  137. FCodingTable := ToBytes(GBase64CodeTable);
  138. FFillChar := '='; {Do not Localize}
  139. end;
  140. { TIdEncoderMIME }
  141. {$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
  142. constructor TIdEncoderMIME.Create(AOwner: TComponent);
  143. begin
  144. inherited Create(AOwner);
  145. end;
  146. {$ENDIF}
  147. procedure TIdEncoderMIME.InitComponent;
  148. begin
  149. inherited InitComponent;
  150. FCodingTable := ToBytes(GBase64CodeTable);
  151. FFillChar := '='; {Do not Localize}
  152. end;
  153. initialization
  154. TIdDecoder4to3.ConstructDecodeTable(GBase64CodeTable, GBase64DecodeTable);
  155. end.