| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- unit IdHeaderCoderBase;
- interface
- {$i IdCompilerDefines.inc}
- uses
- Classes, IdGlobal, IdException;
- type
- TIdHeaderDecodingNeededEvent = procedure(const ACharSet: String; const AData: TIdBytes; var VResult: String; var VHandled: Boolean) of object;
- TIdHeaderEncodingNeededEvent = procedure(const ACharSet, AData: String; var VResult: TIdBytes; var VHandled: Boolean) of object;
- TIdHeaderCoder = class(TObject)
- public
- class function Decode(const ACharSet: String; const AData: TIdBytes): String; virtual;
- class function Encode(const ACharSet, AData: String): TIdBytes; virtual;
- class function CanHandle(const ACharSet: String): Boolean; virtual;
- end;
- TIdHeaderCoderClass = class of TIdHeaderCoder;
- EIdHeaderEncodeError = class(EIdException);
- var
- GHeaderEncodingNeeded: TIdHeaderEncodingNeededEvent = nil;
- GHeaderDecodingNeeded: TIdHeaderDecodingNeededEvent = nil;
- function HeaderCoderByCharSet(const ACharSet: String): TIdHeaderCoderClass;
- function DecodeHeaderData(const ACharSet: String; const AData: TIdBytes; var VResult: String): Boolean;
- function EncodeHeaderData(const ACharSet, AData: String): TIdBytes;
- procedure RegisterHeaderCoder(const ACoder: TIdHeaderCoderClass);
- procedure UnregisterHeaderCoder(const ACoder: TIdHeaderCoderClass);
- implementation
- uses
- {$IFDEF VCL_XE3_OR_ABOVE}
- System.Types,
- {$ENDIF}
- {$IFDEF HAS_UNIT_Generics_Collections}
- System.Generics.Collections,
- {$ENDIF}
- SysUtils, IdResourceStringsProtocols;
- type
- TIdHeaderCoderList = class(TList{$IFDEF HAS_GENERICS_TList}<TIdHeaderCoderClass>{$ENDIF})
- public
- function ByCharSet(const ACharSet: String): TIdHeaderCoderClass;
- end;
- var
- GHeaderCoderList: TIdHeaderCoderList = nil;
- { TIdHeaderCoder }
- class function TIdHeaderCoder.Decode(const ACharSet: String; const AData: TIdBytes): String;
- begin
- Result := '';
- end;
- class function TIdHeaderCoder.Encode(const ACharSet, AData: String): TIdBytes;
- begin
- Result := nil;
- end;
- class function TIdHeaderCoder.CanHandle(const ACharSet: String): Boolean;
- begin
- Result := False;
- end;
- { TIdHeaderCoderList }
- function TIdHeaderCoderList.ByCharSet(const ACharSet: string): TIdHeaderCoderClass;
- var
- I: Integer;
- LCoder: TIdHeaderCoderClass;
- begin
- Result := nil;
- // loop backwards so that user-defined coders can override native coders
- for I := Count-1 downto 0 do begin
- LCoder := TIdHeaderCoderClass(Items[I]);
- if LCoder.CanHandle(ACharSet) then begin
- Result := LCoder;
- Exit;
- end;
- end;
- end;
- function HeaderCoderByCharSet(const ACharSet: String): TIdHeaderCoderClass;
- begin
- if Assigned(GHeaderCoderList) then begin
- Result := GHeaderCoderList.ByCharSet(ACharSet);
- end else begin
- Result := nil;
- end;
- end;
- function DecodeHeaderData(const ACharSet: String; const AData: TIdBytes; var VResult: String): Boolean;
- var
- LCoder: TIdHeaderCoderClass;
- begin
- LCoder := HeaderCoderByCharSet(ACharSet);
- if LCoder <> nil then begin
- VResult := LCoder.Decode(ACharSet, AData);
- Result := True;
- end else
- begin
- VResult := '';
- Result := False;
- if Assigned(GHeaderDecodingNeeded) then begin
- GHeaderDecodingNeeded(ACharSet, AData, VResult, Result);
- end;
- { RLebeau: TODO - enable this?
- if not LDecoded then begin
- raise EIdHeaderDecodeError.Create(RSHeaderDecodeError, [ACharSet]);
- end;
- }
- end;
- end;
- function EncodeHeaderData(const ACharSet, AData: String): TIdBytes;
- var
- LCoder: TIdHeaderCoderClass;
- LEncoded: Boolean;
- begin
- LCoder := HeaderCoderByCharSet(ACharSet);
- if LCoder <> nil then begin
- Result := LCoder.Encode(ACharSet, AData);
- end else
- begin
- Result := nil;
- LEncoded := False;
- if Assigned(GHeaderEncodingNeeded) then begin
- GHeaderEncodingNeeded(ACharSet, AData, Result, LEncoded);
- end;
- if not LEncoded then begin
- raise EIdHeaderEncodeError.CreateFmt(RSHeaderEncodeError, [ACharSet]);
- end;
- end;
- end;
- procedure RegisterHeaderCoder(const ACoder: TIdHeaderCoderClass);
- begin
- if Assigned(ACoder) and
- Assigned(GHeaderCoderList) and
- (GHeaderCoderList.IndexOf(
- {$IFDEF HAS_GENERICS_TList}ACoder{$ELSE}TObject(ACoder){$ENDIF}
- ) = -1) then
- begin
- GHeaderCoderList.Add(
- {$IFDEF HAS_GENERICS_TList}ACoder{$ELSE}TObject(ACoder){$ENDIF}
- );
- end;
- end;
- procedure UnregisterHeaderCoder(const ACoder: TIdHeaderCoderClass);
- begin
- if Assigned(GHeaderCoderList) then begin
- GHeaderCoderList.Remove(
- {$IFDEF HAS_GENERICS_TList}ACoder{$ELSE}TObject(ACoder){$ENDIF}
- );
- end;
- end;
- initialization
- GHeaderCoderList := TIdHeaderCoderList.Create;
- finalization
- FreeAndNil(GHeaderCoderList);
- end.
|