diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bfdd04b --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +__history/ +Test/lib/ +Test/bin/ +*.tvsconfig +*.local +*.identcache diff --git a/X2Log.Decorator.pas b/X2Log.Decorator.pas index 0d9237b..c2f5198 100644 --- a/X2Log.Decorator.pas +++ b/X2Log.Decorator.pas @@ -37,15 +37,19 @@ type procedure Verbose(const AMessage: string; const ADetails: string = ''); procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure VerboseS(const AMessage: string; ANamedParams: array of const); procedure Info(const AMessage: string; const ADetails: string = ''); procedure InfoEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure InfoS(const AMessage: string; ANamedParams: array of const); procedure Warning(const AMessage: string; const ADetails: string = ''); procedure WarningEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure WarningS(const AMessage: string; ANamedParams: array of const); procedure Error(const AMessage: string; const ADetails: string = ''); procedure ErrorEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure ErrorS(const AMessage: string; ANamedParams: array of const); procedure Exception(AException: Exception; const AMessage: string = ''); procedure ExceptionEx(AException: Exception; const AMessage: string = ''; const ACategory: string = ''); @@ -126,6 +130,13 @@ begin end; +procedure TX2LogCategoryDecorator.VerboseS(const AMessage: string; ANamedParams: array of const); +begin + if Assigned(DecoratedLog) then + DecoratedLog.Log(TX2LogLevel.Verbose, Now, AMessage, CategoryName, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams)); +end; + + procedure TX2LogCategoryDecorator.Info(const AMessage, ADetails: string); begin if Assigned(DecoratedLog) then @@ -140,6 +151,12 @@ begin end; +procedure TX2LogCategoryDecorator.InfoS(const AMessage: string; ANamedParams: array of const); +begin + if Assigned(DecoratedLog) then + DecoratedLog.Log(TX2LogLevel.Info, Now, AMessage, CategoryName, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams)); +end; + procedure TX2LogCategoryDecorator.Warning(const AMessage, ADetails: string); begin if Assigned(DecoratedLog) then @@ -154,6 +171,12 @@ begin end; +procedure TX2LogCategoryDecorator.WarningS(const AMessage: string; ANamedParams: array of const); +begin + if Assigned(DecoratedLog) then + DecoratedLog.Log(TX2LogLevel.Warning, Now, AMessage, CategoryName, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams)); +end; + procedure TX2LogCategoryDecorator.Error(const AMessage, ADetails: string); begin if Assigned(DecoratedLog) then @@ -168,6 +191,13 @@ begin end; +procedure TX2LogCategoryDecorator.ErrorS(const AMessage: string; ANamedParams: array of const); +begin + if Assigned(DecoratedLog) then + DecoratedLog.Log(TX2LogLevel.Error, Now, AMessage, CategoryName, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams)); +end; + + procedure TX2LogCategoryDecorator.Exception(AException: Exception; const AMessage: string); begin if Assigned(DecoratedLog) then diff --git a/X2Log.Details.Default.pas b/X2Log.Details.Default.pas index 7329e9d..1931934 100644 --- a/X2Log.Details.Default.pas +++ b/X2Log.Details.Default.pas @@ -3,6 +3,7 @@ unit X2Log.Details.Default; interface uses System.Classes, + System.Generics.Collections, Vcl.Graphics, X2Log.Details.Intf, @@ -33,6 +34,29 @@ type end; + TX2LogDictionaryDetails = class(TInterfacedObject, IX2LogDetails, IX2LogDetailsDictionary, + IX2LogDetailsCopyable, IX2LogDetailsStreamable) + private + FValues: TDictionary; + public + class function CreateIfNotEmpty(AValues: array of const): TX2LogDictionaryDetails; + + constructor Create(AValues: array of const); + destructor Destroy; override; + + { IX2LogDetails } + function GetSerializerIID: TGUID; + + { IX2LogDetailsDictionary } + function GetValue(const Key: string): Variant; + + { IX2LogDetailsCopyable } + procedure CopyToClipboard; + + { IX2LogDetailsStreamable } + procedure SaveToStream(AStream: TStream); + end; + TX2LogBinaryDetails = class(TInterfacedObject, IX2LogDetails, IX2LogDetailsBinary, IX2LogDetailsStreamable) @@ -98,6 +122,7 @@ uses const StringDetailsSerializerIID: TGUID = '{4223C30E-6E80-4D66-9EDC-F8688A7413D2}'; + DictionaryDetailsSerializerIID: TGUID = '{1D28FF6E-8AA7-41FA-96D7-0CE921D9CA2E}'; BinaryDetailsSerializerIID: TGUID = '{05F6E8BD-118E-41B3-B626-1F190CC2A7D3}'; GraphicDetailsSerializerIID: TGUID = '{BD31E42A-83DC-4947-A862-79ABAE8D5056}'; @@ -112,6 +137,14 @@ type end; + TX2LogDictionaryDetailsSerializer = class(TInterfacedObject, IX2LogDetailsSerializer) + public + { IX2LogDetailsSerializer } + procedure Serialize(ADetails: IX2LogDetails; AStream: TStream); + function Deserialize(AStream: TStream): IX2LogDetails; + end; + + TX2LogBinaryDetailsSerializer = class(TInterfacedObject, IX2LogDetailsSerializer) public { IX2LogDetailsSerializer } @@ -178,6 +211,58 @@ begin end; +{ TX2LogDictionaryDetails } +class function TX2LogDictionaryDetails.CreateIfNotEmpty(AValues: array of const): TX2LogDictionaryDetails; +begin + if Length(AValues) > 0 then + Result := TX2LogDictionaryDetails.Create(AValues) + else + Result := nil; +end; + + +constructor TX2LogDictionaryDetails.Create(AValues: array of const); +begin + inherited Create; + + FValues := TDictionary.Create(); + + // TODO parse AValues +end; + + +destructor TX2LogDictionaryDetails.Destroy; +begin + FreeAndNil(FValues); + + inherited Destroy; +end; + + +function TX2LogDictionaryDetails.GetSerializerIID: TGUID; +begin + Result := DictionaryDetailsSerializerIID; +end; + + +function TX2LogDictionaryDetails.GetValue(const Key: string): Variant; +begin + // TODO +end; + + +procedure TX2LogDictionaryDetails.CopyToClipboard; +begin + // TODO +end; + + +procedure TX2LogDictionaryDetails.SaveToStream(AStream: TStream); +begin + // TODO +end; + + { TX2LogBinaryDetails } constructor TX2LogBinaryDetails.Create; begin @@ -311,6 +396,18 @@ begin end; +{ TX2LogDictionaryDetailsSerializer } +function TX2LogDictionaryDetailsSerializer.Deserialize(AStream: TStream): IX2LogDetails; +begin + // TODO +end; + +procedure TX2LogDictionaryDetailsSerializer.Serialize(ADetails: IX2LogDetails; AStream: TStream); +begin + // TODO +end; + + { TX2LogBinaryDetailsSerializer } procedure TX2LogBinaryDetailsSerializer.Serialize(ADetails: IX2LogDetails; AStream: TStream); var @@ -376,6 +473,7 @@ end; initialization TX2LogDetailsRegistry.Register(StringDetailsSerializerIID, TX2LogStringDetailsSerializer.Create); + TX2LogDetailsRegistry.Register(DictionaryDetailsSerializerIID, TX2LogDictionaryDetailsSerializer.Create); TX2LogDetailsRegistry.Register(BinaryDetailsSerializerIID, TX2LogBinaryDetailsSerializer.Create); TX2LogDetailsRegistry.Register(GraphicDetailsSerializerIID, TX2LogGraphicDetailsSerializer.Create); diff --git a/X2Log.Details.Intf.pas b/X2Log.Details.Intf.pas index fff8720..a1f527e 100644 --- a/X2Log.Details.Intf.pas +++ b/X2Log.Details.Intf.pas @@ -17,6 +17,14 @@ type end; + IX2LogDetailsDictionary = interface(IX2LogDetails) + ['{24211DC0-F359-466B-A9CD-AF6AA3AE85F4}'] + function GetValue(const Key: string): Variant; + + property Values[const Key: string]: Variant read GetValue; + end; + + IX2LogDetailsBinary = interface(IX2LogDetails) ['{265739E7-BB65-434B-BCD3-BB89B936A854}'] function GetAsStream: TStream; diff --git a/X2Log.Intf.pas b/X2Log.Intf.pas index 3f51543..17b3700 100644 --- a/X2Log.Intf.pas +++ b/X2Log.Intf.pas @@ -79,47 +79,23 @@ type procedure Verbose(const AMessage: string; const ADetails: string = ''); procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure VerboseS(const AMessage: string; ANamedParams: array of const); overload; procedure Info(const AMessage: string; const ADetails: string = ''); procedure InfoEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure InfoS(const AMessage: string; ANamedParams: array of const); overload; procedure Warning(const AMessage: string; const ADetails: string = ''); procedure WarningEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure WarningS(const AMessage: string; ANamedParams: array of const); overload; procedure Error(const AMessage: string; const ADetails: string = ''); procedure ErrorEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure ErrorS(const AMessage: string; ANamedParams: array of const); overload; procedure Exception(AException: Exception; const AMessage: string = ''); procedure ExceptionEx(AException: Exception; const AMessage: string = ''; const ACategory: string = ''); end; - - - - TX2LogMessageHeaderV1 = packed record - ID: Word; - Version: Byte; - Size: Word; - DateTime: TDateTime; - Level: TX2LogLevel; - - { - Payload: - - CategoryLength: Cardinal - Category: WideString - MessageLength: Cardinal - Message: WideString - DetailsLength: Cardinal - Details: WideString - } - end; - - - TX2LogMessageHeader = TX2LogMessageHeaderV1; - -const - X2LogMessageHeader: Word = $B258; - X2LogMessageVersion: Byte = 1; implementation diff --git a/X2Log.pas b/X2Log.pas index 89a2eaf..500e596 100644 --- a/X2Log.pas +++ b/X2Log.pas @@ -26,15 +26,19 @@ type procedure Verbose(const AMessage: string; const ADetails: string = ''); procedure VerboseEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure VerboseS(const AMessage: string; ANamedParams: array of const); procedure Info(const AMessage: string; const ADetails: string = ''); procedure InfoEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure InfoS(const AMessage: string; ANamedParams: array of const); procedure Warning(const AMessage: string; const ADetails: string = ''); procedure WarningEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure WarningS(const AMessage: string; ANamedParams: array of const); procedure Error(const AMessage: string; const ADetails: string = ''); procedure ErrorEx(const AMessage: string; ADetails: IX2LogDetails = nil); + procedure ErrorS(const AMessage: string; ANamedParams: array of const); procedure Exception(AException: Exception; const AMessage: string = ''); procedure ExceptionEx(AException: Exception; const AMessage: string = ''; const ACategory: string = ''); @@ -85,6 +89,12 @@ begin end; +procedure TX2Log.VerboseS(const AMessage: string; ANamedParams: array of const); +begin + Log(TX2LogLevel.Verbose, Now, AMessage, LogCategoryDefault, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams)); +end; + + procedure TX2Log.Info(const AMessage, ADetails: string); begin Log(TX2LogLevel.Info, AMessage, LogCategoryDefault, TX2LogStringDetails.CreateIfNotEmpty(ADetails)); @@ -97,6 +107,12 @@ begin end; +procedure TX2Log.InfoS(const AMessage: string; ANamedParams: array of const); +begin + Log(TX2LogLevel.Info, Now, AMessage, LogCategoryDefault, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams)); +end; + + procedure TX2Log.Warning(const AMessage, ADetails: string); begin Log(TX2LogLevel.Warning, AMessage, LogCategoryDefault, TX2LogStringDetails.CreateIfNotEmpty(ADetails)); @@ -109,6 +125,12 @@ begin end; +procedure TX2Log.WarningS(const AMessage: string; ANamedParams: array of const); +begin + Log(TX2LogLevel.Warning, Now, AMessage, LogCategoryDefault, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams)); +end; + + procedure TX2Log.Error(const AMessage, ADetails: string); begin Log(TX2LogLevel.Error, AMessage, LogCategoryDefault, TX2LogStringDetails.CreateIfNotEmpty(ADetails)); @@ -121,6 +143,12 @@ begin end; +procedure TX2Log.ErrorS(const AMessage: string; ANamedParams: array of const); +begin + Log(TX2LogLevel.Error, Now, AMessage, LogCategoryDefault, TX2LogDictionaryDetails.CreateIfNotEmpty(ANamedParams)); +end; + + procedure TX2Log.Exception(AException: Exception; const AMessage: string); begin ExceptionEx(AException, AMessage, LogCategoryDefault);