IdMessageHelper.pas 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. unit IdMessageHelper;
  2. {$I IdCompilerDefines.inc}
  3. interface
  4. uses
  5. Classes, IdMessage;
  6. // TODO: move this to IdCompilerDefines.inc
  7. {$IFDEF DCC}
  8. // class helpers were first introduced in D2005, but were buggy and not
  9. // officially supported until D2006...
  10. {$IFDEF VCL_2006_OR_ABOVE}
  11. {$DEFINE HAS_CLASS_HELPER}
  12. {$ENDIF}
  13. {$ENDIF}
  14. {$IFDEF FPC}
  15. {$IFDEF FPC_2_6_0_OR_ABOVE}
  16. {$DEFINE HAS_CLASS_HELPER}
  17. {$ENDIF}
  18. {$ENDIF}
  19. {$IFDEF HAS_CLASS_HELPER}
  20. type
  21. TIdMessageHelper = class helper for TIdMessage
  22. public
  23. procedure LoadFromFile(const AFileName: string; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); overload;
  24. procedure LoadFromStream(AStream: TStream; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); overload;
  25. procedure SaveToFile(const AFileName: string; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); overload;
  26. procedure SaveToStream(AStream: TStream; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); overload;
  27. end;
  28. {$ENDIF}
  29. procedure TIdMessageHelper_LoadFromFile(AMsg: TIdMessage; const AFileName: string; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.LoadFromFile()'{$ENDIF};{$ENDIF}{$ENDIF}
  30. procedure TIdMessageHelper_LoadFromStream(AMsg: TIdMessage; AStream: TStream; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.LoadFromStream()'{$ENDIF};{$ENDIF}{$ENDIF}
  31. procedure TIdMessageHelper_SaveToFile(AMsg: TIdMessage; const AFileName: string; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.SaveToFile()'{$ENDIF};{$ENDIF}{$ENDIF}
  32. procedure TIdMessageHelper_SaveToStream(AMsg: TIdMessage; AStream: TStream; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.SaveToStream()'{$ENDIF};{$ENDIF}{$ENDIF}
  33. implementation
  34. uses
  35. IdGlobal, IdMessageClient, SysUtils, IdResourceStringsProtocols;
  36. { TIdMessageClientHelper }
  37. procedure Internal_TIdMessageClientHelper_ProcessMessage(AClient: TIdMessageClient;
  38. AMsg: TIdMessage; AStream: TStream; AHeaderOnly: Boolean;
  39. AUsesDotTransparency: Boolean);
  40. var
  41. LIOHandler: TIdIOHandlerStreamMsg;
  42. begin
  43. if AUsesDotTransparency then begin
  44. AClient.ProcessMessage(AMsg, AStream, AHeaderOnly);
  45. end else
  46. begin
  47. LIOHandler := TIdIOHandlerStreamMsg.Create(nil, AStream);
  48. try
  49. LIOHandler.FreeStreams := False;
  50. LIOHandler.EscapeLines := True; // <-- this is the key!
  51. AClient.IOHandler := LIOHandler;
  52. try
  53. LIOHandler.Open;
  54. AClient.ProcessMessage(AMsg, AHeaderOnly);
  55. finally
  56. AClient.IOHandler := nil;
  57. end;
  58. finally
  59. LIOHandler.Free;
  60. end;
  61. end;
  62. end;
  63. { TIdMessageHelper }
  64. procedure Internal_TIdMessageHelper_LoadFromStream(AMsg: TIdMessage; AStream: TStream;
  65. const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean);
  66. var
  67. LMsgClient: TIdMessageClient;
  68. begin
  69. if AUsesDotTransparency then begin
  70. AMsg.LoadFromStream(AStream, AHeadersOnly);
  71. end else
  72. begin
  73. // clear message properties, headers before loading
  74. AMsg.Clear;
  75. LMsgClient := TIdMessageClient.Create;
  76. try
  77. Internal_TIdMessageClientHelper_ProcessMessage(LMsgClient, AMsg, AStream, AHeadersOnly, False);
  78. finally
  79. LMsgClient.Free;
  80. end;
  81. end;
  82. end;
  83. {$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF}
  84. procedure TIdMessageHelper_LoadFromStream(AMsg: TIdMessage; AStream: TStream;
  85. const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean);
  86. {$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF}
  87. begin
  88. Internal_TIdMessageHelper_LoadFromStream(AMsg, AStream, AHeadersOnly, AUsesDotTransparency);
  89. end;
  90. {$IFDEF HAS_CLASS_HELPER}
  91. procedure TIdMessageHelper.LoadFromStream(AStream: TStream; const AHeadersOnly: Boolean;
  92. const AUsesDotTransparency: Boolean);
  93. begin
  94. Internal_TIdMessageHelper_LoadFromStream(Self, AStream, AHeadersOnly, AUsesDotTransparency);
  95. end;
  96. {$ENDIF}
  97. procedure Internal_TIdMessageHelper_LoadFromFile(AMsg: TIdMessage; const AFileName: string;
  98. const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean);
  99. var
  100. LStream: TIdReadFileExclusiveStream;
  101. begin
  102. if AUsesDotTransparency then begin
  103. AMsg.LoadFromFile(AFileName, AHeadersOnly);
  104. end else
  105. begin
  106. try
  107. LStream := TIdReadFileExclusiveStream.Create(AFilename);
  108. except
  109. LStream := nil; // keep the compiler happy
  110. IndyRaiseOuterException(EIdMessageCannotLoad.CreateFmt(RSIdMessageCannotLoad, [AFilename]));
  111. end;
  112. try
  113. Internal_TIdMessageHelper_LoadFromStream(AMsg, LStream, AHeadersOnly, False);
  114. finally
  115. LStream.Free;
  116. end;
  117. end;
  118. end;
  119. {$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF}
  120. procedure TIdMessageHelper_LoadFromFile(AMsg: TIdMessage; const AFileName: string;
  121. const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean);
  122. {$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF}
  123. begin
  124. Internal_TIdMessageHelper_LoadFromFile(AMsg, AFileName, AHeadersOnly, AUsesDotTransparency);
  125. end;
  126. {$IFDEF HAS_CLASS_HELPER}
  127. procedure TIdMessageHelper.LoadFromFile(const AFileName: string; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean);
  128. begin
  129. Internal_TIdMessageHelper_LoadFromFile(Self, AFileName, AHeadersOnly, AUsesDotTransparency);
  130. end;
  131. {$ENDIF}
  132. procedure Internal_TIdMessageHelper_SaveToStream(AMsg: TIdMessage; AStream: TStream;
  133. const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean);
  134. var
  135. LMsgClient: TIdMessageClient;
  136. LIOHandler: TIdIOHandlerStreamMsg;
  137. begin
  138. if AUseDotTransparency then begin
  139. AMsg.SaveToStream(AStream, AHeadersOnly);
  140. end else
  141. begin
  142. LMsgClient := TIdMessageClient.Create(nil);
  143. try
  144. LIOHandler := TIdIOHandlerStreamMsg.Create(nil, nil, AStream);
  145. try
  146. LIOHandler.FreeStreams := False;
  147. LIOHandler.UnescapeLines := True; // <-- this is the key!
  148. LMsgClient.IOHandler := LIOHandler;
  149. try
  150. LMsgClient.SendMsg(AMsg, AHeadersOnly);
  151. {
  152. // add the end of message marker when body is included
  153. if not AHeadersOnly then begin
  154. LIOHandler.WriteLn('.'); {do not localize
  155. end;
  156. }
  157. finally
  158. LMsgClient.IOHandler := nil;
  159. end;
  160. finally
  161. LIOHandler.Free;
  162. end;
  163. finally
  164. LMsgClient.Free;
  165. end;
  166. end;
  167. end;
  168. {$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF}
  169. procedure TIdMessageHelper_SaveToStream(AMsg: TIdMessage; AStream: TStream;
  170. const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean);
  171. {$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF}
  172. begin
  173. Internal_TIdMessageHelper_SaveToStream(AMsg, AStream, AHeadersOnly, AUseDotTransparency);
  174. end;
  175. {$IFDEF HAS_CLASS_HELPER}
  176. procedure TIdMessageHelper.SaveToStream(AStream: TStream; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean);
  177. begin
  178. Internal_TIdMessageHelper_SaveToStream(Self, AStream, AHeadersOnly, AUseDotTransparency);
  179. end;
  180. {$ENDIF}
  181. type
  182. TIdMessageAccess = class(TIdMessage)
  183. end;
  184. procedure Internal_TIdMessageHelper_SaveToFile(AMsg: TIdMessage; const AFileName: string;
  185. const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean);
  186. var
  187. LStream : TFileStream;
  188. LMsgAccess: TIdMessageAccess;
  189. begin
  190. if AUseDotTransparency then begin
  191. AMsg.SaveToFile(AFileName, AHeadersOnly);
  192. end else
  193. begin
  194. LStream := TIdFileCreateStream.Create(AFileName);
  195. try
  196. {$I IdObjectChecksOff.inc}
  197. LMsgAccess := TIdMessageAccess(AMsg);
  198. {$I IdObjectChecksOn.inc}
  199. LMsgAccess.FSavingToFile := True;
  200. try
  201. Internal_TIdMessageHelper_SaveToStream(AMsg, LStream, AHeadersOnly, False);
  202. finally
  203. LMsgAccess.FSavingToFile := False;
  204. end;
  205. finally
  206. LStream.Free;
  207. end;
  208. end;
  209. end;
  210. {$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF}
  211. procedure TIdMessageHelper_SaveToFile(AMsg: TIdMessage; const AFileName: string;
  212. const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean);
  213. {$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF}
  214. begin
  215. Internal_TIdMessageHelper_SaveToFile(AMsg, AFileName, AHeadersOnly, AUseDotTransparency);
  216. end;
  217. {$IFDEF HAS_CLASS_HELPER}
  218. procedure TIdMessageHelper.SaveToFile(const AFileName: string; const AHeadersOnly: Boolean;
  219. const AUseDotTransparency: Boolean);
  220. begin
  221. Internal_TIdMessageHelper_SaveToFile(Self, AFileName, AHeadersOnly, AUseDotTransparency);
  222. end;
  223. {$ENDIF}
  224. end.