IdCoder00E.pas 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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.4 2004.05.20 1:39:26 PM czhower
  18. Last of the IdStream updates
  19. Rev 1.3 2004.05.20 11:37:20 AM czhower
  20. IdStreamVCL
  21. Rev 1.2 2004.05.20 11:13:16 AM czhower
  22. More IdStream conversions
  23. Rev 1.1 2003.06.13 6:57:10 PM czhower
  24. Speed improvement
  25. Rev 1.0 2003.06.13 4:59:36 PM czhower
  26. Initial checkin
  27. }
  28. unit IdCoder00E;
  29. interface
  30. {$i IdCompilerDefines.inc}
  31. uses
  32. Classes,
  33. IdCoder3to4;
  34. type
  35. TIdDecoder00E = class(TIdDecoder4to3)
  36. public
  37. procedure Decode(ASrcStream: TStream; const ABytes: Integer = -1); override;
  38. end;
  39. TIdEncoder00E = class(TIdEncoder3to4)
  40. public
  41. procedure Encode(ASrcStream, ADestStream: TStream; const ABytes: Integer = -1); override;
  42. end;
  43. implementation
  44. uses
  45. IdGlobal,
  46. SysUtils;
  47. { TIdDecoder00E }
  48. procedure TIdDecoder00E.Decode(ASrcStream: TStream; const ABytes: Integer = -1);
  49. var
  50. LFirstByte: Byte;
  51. LBuf: TIdBytes;
  52. LSize: Int64;
  53. LDataLen, LExpected: Integer;
  54. begin
  55. LSize := IndyLength(ASrcStream, ABytes);
  56. if LSize > 0 then begin
  57. //Param 2 - Start at second char since 00E's have byte 1 as length
  58. ASrcStream.ReadBuffer(LFirstByte, 1);
  59. //Param 3 - Get output length of input. This is length in bytes,
  60. // not encoded chars. DO NOT include fill chars in calculation
  61. {Assert(Ord(FDecodeTable[LFirstByte]) = (((LSize-1) div 4) * 3));}
  62. LDataLen := FDecodeTable[LFirstByte];
  63. SetLength(LBuf, LSize-1);
  64. ASrcStream.ReadBuffer(PByte(LBuf)^, LSize-1);
  65. // RLebeau 4/28/2014: encountered a situation where a UUE encoded attachment
  66. // had some encoded lines that were supposed to end with a space character
  67. // but were actually truncated off. Turns out that Outlook Express is known
  68. // for doing that, for instance. Some other encoding apps might also have a
  69. // similar flaw, so just in case let's calculate what the input length is
  70. // supposed to be and pad the input with spaces if needed before then
  71. // decoding it...
  72. LExpected := ((LDataLen + 2) div 3) * 4;
  73. if Length(LBuf) < LExpected then begin
  74. ExpandBytes(LBuf, Length(LBuf), LExpected-Length(LBuf), Ord(' ')); // should this use FillChar instead?
  75. end;
  76. LBuf := InternalDecode(LBuf, True);
  77. if Assigned(FStream) then begin
  78. FStream.WriteBuffer(PByte(LBuf)^, LDataLen);
  79. end;
  80. end;
  81. end;
  82. { TIdEncoder00E }
  83. procedure TIdEncoder00E.Encode(ASrcStream, ADestStream: TStream; const ABytes: Integer = -1);
  84. var
  85. LStream: TMemoryStream;
  86. LSize: Int64;
  87. LEncodeSize: Integer;
  88. LByte: Byte;
  89. begin
  90. LStream := TMemoryStream.Create;
  91. try
  92. LSize := IndyLength(ASrcStream, ABytes);
  93. while LSize > 0 do
  94. begin
  95. LEncodeSize := IndyMin(LSize, Length(FCodingTable)-1);
  96. inherited Encode(ASrcStream, LStream, LEncodeSize);
  97. Dec(LSize, LEncodeSize);
  98. LByte := FCodingTable[Integer(LEncodeSize)];
  99. ADestStream.WriteBuffer(LByte, 1);
  100. LStream.Position := 0;
  101. ADestStream.CopyFrom(LStream, 0);
  102. if LSize > 0 then begin
  103. WriteStringToStream(ADestStream, EOL);
  104. LStream.Clear;
  105. end;
  106. end;
  107. finally
  108. LStream.Free;
  109. end;
  110. end;
  111. end.