From 805c6ae050082b500b6f9e3ba64fb77c21fcd223 Mon Sep 17 00:00:00 2001 From: danieleteti Date: Tue, 28 Jun 2016 15:21:47 +0200 Subject: [PATCH] BUG fixes + deprecations --- StompClient.pas | 156 +++++--- StompTypes.pas | 64 +++- test/MainU.pas | 4 +- test/teststompclient.dproj | 651 ++++++++++++++++++++++----------- unittest/TestStompClient.dproj | 320 +++++++++------- unittest/TestStompClient.res | Bin 6040 -> 6532 bytes 6 files changed, 787 insertions(+), 408 deletions(-) diff --git a/StompClient.pas b/StompClient.pas index 56b69887..c668dc2b 100644 --- a/StompClient.pas +++ b/StompClient.pas @@ -34,6 +34,7 @@ uses IdTCPClient, IdException, IdExceptionCore, + IdHeaderList, {$ELSE} synsock, @@ -84,7 +85,7 @@ type procedure DeInit; procedure MergeHeaders(var AFrame: IStompFrame; var AHeaders: IStompHeaders); procedure SendFrame(AFrame: IStompFrame); - + function FormatErrorFrame(const AErrorFrame: IStompFrame): String; public function SetPassword(const Value: string): IStompClient; function SetUserName(const Value: string): IStompClient; @@ -137,6 +138,7 @@ const uses // Windows, // Remove windows unit for compiling on ios IdGlobal, + IdGlobalProtocols, Character; {$ENDIF} @@ -261,7 +263,7 @@ begin while Frame = nil do Frame := Receive; if Frame.GetCommand = 'ERROR' then - raise EStomp.Create(Frame.output); + raise EStomp.Create(FormatErrorFrame(Frame)); if Frame.GetCommand = 'CONNECTED' then begin FSession := Frame.GetHeaders.Value('session'); @@ -344,6 +346,13 @@ begin DeInit; end; +function TStompClient.FormatErrorFrame(const AErrorFrame: IStompFrame): String; +begin + if AErrorFrame.GetCommand <> 'ERROR' then + raise EStomp.Create('Not an ERROR frame'); + Result := AErrorFrame.GetHeaders.Value('message') + ': ' + AErrorFrame.GetBody; +end; + function TStompClient.GetProtocolVersion: string; begin Result := FServerProtocolVersion; @@ -497,72 +506,115 @@ function TStompClient.Receive(ATimeout: Integer): IStompFrame; {$ELSE} function InternalReceiveINDY(ATimeout: Integer): IStompFrame; var - c: char; - sb: TStringBuilder; - tout: boolean; - FirstValidChar: boolean; - // UTF8Encoding: TEncoding; + s: string; + lSBuilder: TStringBuilder; + Headers: TIdHeaderList; + ContentLength: Integer; + Charset: string; + {$IF CompilerVersion < 24} - UTF8Encoding: TIdTextEncoding; + Encoding: TIdTextEncoding; + FreeEncoding: boolean; {$ELSE} - UTF8Encoding: IIdTextEncoding; -{$IFEND} - begin -{$IF CompilerVersion < 24} - UTF8Encoding := TEncoding.UTF8; -{$ELSE} - UTF8Encoding := IndyTextEncoding_UTF8(); + Encoding: IIdTextEncoding; {$ENDIF} - tout := False; + begin Result := nil; + lSBuilder := TStringBuilder.Create(1024 * 4); try - sb := TStringBuilder.Create(1024 * 4); + FTCP.ReadTimeout := ATimeout; + FTCP.Socket.DefStringEncoding := +{$IF CompilerVersion < 24}TIdTextEncoding.UTF8{$ELSE}IndyTextEncoding_UTF8{$ENDIF}; + try - FTCP.ReadTimeout := ATimeout; + // read command line + repeat + s := FTCP.Socket.ReadLn; + until s <> ''; + lSBuilder.Append(s + LF); + + // read headers + Headers := TIdHeaderList.Create(QuotePlain); + try - FirstValidChar := False; - FTCP.Socket.CheckForDataOnSource(1); - while True do - begin - c := FTCP.Socket.ReadChar(UTF8Encoding); - if (c = LF) and (not FirstValidChar) then - Continue; - FirstValidChar := True; - if c <> CHAR0 then - sb.Append(c) - else - begin - // FTCP.IOHandler.ReadChar(TEncoding.UTF8); + repeat + s := FTCP.Socket.ReadLn; + lSBuilder.Append(s + LF); + if s = '' then Break; - end; - end; - except - on E: EIdReadTimeout do + Headers.Add(s); + until False; + + // read body + // + // NOTE: non-text data really should be read as a Stream instead of a String!!! + // + + if IsHeaderMediaType(Headers.Values['content-type'], 'text') then begin - tout := True; - end; - on E: Exception do + Charset := Headers.Params['content-type', 'charset']; + if Charset = '' then + Charset := 'utf-8'; + Encoding := CharsetToEncoding(Charset); +{$IF CompilerVersion < 24} + FreeEncoding := True; +{$ENDIF} + end + else begin - if sb.Length > 0 then - raise EStomp.Create(E.message + sLineBreak + sb.toString) + Encoding := IndyTextEncoding_8Bit(); +{$IF CompilerVersion < 24} + FreeEncoding := False; +{$ENDIF} + end; + +{$IF CompilerVersion < 24} + try +{$ENDIF} + if Headers.IndexOfName('content-length') <> -1 then + begin + // length specified, read exactly that many bytes + ContentLength := IndyStrToInt(Headers.Values['content-length']); + if ContentLength > 0 then + begin + s := FTCP.Socket.ReadString(ContentLength, Encoding); + lSBuilder.Append(s); + end; + // frame must still be terminated by a null + FTCP.Socket.ReadLn(#0); + end else - raise; + + begin + // no length specified, body terminated by frame terminating null + s := FTCP.Socket.ReadLn(#0, Encoding); + lSBuilder.Append(s); + + end; + lSBuilder.Append(#0); +{$IF CompilerVersion < 24} + finally + if FreeEncoding then + Encoding.Free; end; +{$ENDIF} + finally + Headers.Free; end; - if not tout then + except + on E: Exception do begin - Result := StompUtils.CreateFrame(sb.toString + CHAR0); - if Result.GetCommand = 'ERROR' then - raise EStomp.Create(Result.GetHeaders.Value('message')); + if lSBuilder.Length > 0 then + raise EStomp.Create(E.message + sLineBreak + lSBuilder.toString) + else + raise; end; - finally - sb.Free; - end; - except - on E: Exception do - begin - raise; end; + Result := StompUtils.CreateFrame(lSBuilder.toString); + if Result.GetCommand = 'ERROR' then + raise EStomp.Create(FormatErrorFrame(Result)); + finally + lSBuilder.Free; end; end; diff --git a/StompTypes.pas b/StompTypes.pas index bd08fdb0..590ff3e3 100644 --- a/StompTypes.pas +++ b/StompTypes.pas @@ -108,10 +108,16 @@ type procedure SetItems(index: Cardinal; const Value: TKeyValue); public - class function NewDurableSubscriptionHeader(const SubscriptionName: string) - : TKeyValue; + class function NewDurableSubscriptionHeader(const SubscriptionName: string): TKeyValue; + deprecated 'Use Subscription instead'; class function NewPersistentHeader(const Value: Boolean): TKeyValue; + deprecated 'Use Persistent instead'; class function NewReplyToHeader(const DestinationName: string): TKeyValue; + deprecated 'Use ReplyTo instead'; + + class function Subscription(const SubscriptionName: string): TKeyValue; + class function Persistent(const Value: Boolean): TKeyValue; + class function ReplyTo(const DestinationName: string): TKeyValue; /// /////////////////////////////////////////////7 const @@ -198,7 +204,8 @@ type class function StripLastChar(Buf: string; LastChar: char): string; class function CreateFrame(Buf: string): TStompFrame; class function AckModeToStr(AckMode: TAckMode): string; - class function NewHeaders: IStompHeaders; + class function NewHeaders: IStompHeaders; deprecated 'Use Headers instead'; + class function Headers: IStompHeaders; class function NewFrame: IStompFrame; class function TimestampAsDateTime(const HeaderValue: string): TDateTime; class function NewStomp(Host: string = '127.0.0.1'; @@ -207,12 +214,24 @@ type AcceptVersion: TStompAcceptProtocol = STOMP_Version_1_0): IStompClient; end; +function NewStompClient(Host: string = '127.0.0.1'; + Port: Integer = DEFAULT_STOMP_PORT; ClientID: string = ''; + const UserName: string = 'guest'; const Password: string = 'guest'; + AcceptVersion: TStompAcceptProtocol = STOMP_Version_1_0): IStompClient; + implementation uses Dateutils, StompClient; +function NewStompClient(Host: string; Port: Integer; ClientID: string; + const UserName, Password: string; + AcceptVersion: TStompAcceptProtocol): IStompClient; +begin + Result := StompUtils.NewStomp(Host, Port, ClientID, UserName, Password, AcceptVersion); +end; + class function StompUtils.NewStomp(Host: string = '127.0.0.1'; Port: Integer = DEFAULT_STOMP_PORT; ClientID: string = ''; const UserName: string = 'guest'; const Password: string = 'guest'; @@ -237,27 +256,24 @@ end; class function TStompHeaders.NewDurableSubscriptionHeader(const SubscriptionName : string): TKeyValue; begin - Result.Key := 'activemq.subscriptionName'; - Result.Value := SubscriptionName; + Result := Subscription(SubscriptionName); end; class function TStompHeaders.NewPersistentHeader(const Value: Boolean) : TKeyValue; begin - Result.Key := 'persistent'; - Result.Value := LowerCase(BoolToStr(Value, true)); + Result := Persistent(Value); end; class function TStompHeaders.NewReplyToHeader(const DestinationName: string) : TKeyValue; begin - Result.Key := 'reply-to'; - Result.Value := DestinationName; + Result := ReplyTo(DestinationName); end; class function StompUtils.NewHeaders: IStompHeaders; begin - Result := TStompHeaders.Create; + Result := Headers; end; class function StompUtils.TimestampAsDateTime(const HeaderValue: string) @@ -397,7 +413,7 @@ begin other := StripLastChar(other, COMMAND_END); if TEncoding.UTF8.GetByteCount(other) <> contLen then - // there is still the command_end + // there is still the command_end raise EStomp.Create('frame too short'); Result.Body := other; end @@ -420,6 +436,11 @@ begin end; end; +class function StompUtils.Headers: IStompHeaders; +begin + Result := TStompHeaders.Create; +end; + class function StompUtils.NewFrame: IStompFrame; begin Result := TStompFrame.Create; @@ -506,6 +527,12 @@ begin Result := LINE_END; end; +class function TStompHeaders.Persistent(const Value: Boolean): TKeyValue; +begin + Result.Key := 'persistent'; + Result.Value := LowerCase(BoolToStr(Value, true)); +end; + function TStompHeaders.Remove(Key: string): IStompHeaders; var p: Integer; @@ -516,6 +543,12 @@ begin Result := self; end; +class function TStompHeaders.ReplyTo(const DestinationName: string): TKeyValue; +begin + Result.Key := 'reply-to'; + Result.Value := DestinationName; +end; + procedure TStompHeaders.SetItems(index: Cardinal; const Value: TKeyValue); var p: Integer; @@ -530,6 +563,13 @@ begin raise EStomp.Create('Error SetItems'); end; +class function TStompHeaders.Subscription( + const SubscriptionName: string): TKeyValue; +begin + Result.Key := 'id'; + Result.Value := SubscriptionName; +end; + function TStompHeaders.Value(Key: string): string; var i: Integer; @@ -555,7 +595,7 @@ var frame: IStompFrame; StopListen: Boolean; begin - StopListen := False; + StopListen := false; while not terminated do begin if FStompClient.Receive(frame, 1000) then diff --git a/test/MainU.pas b/test/MainU.pas index 2103bcce..9f7e07a2 100644 --- a/test/MainU.pas +++ b/test/MainU.pas @@ -144,8 +144,8 @@ begin begin stomp.Send('/topic/foo.bar', message_data, StompUtils.NewHeaders.Add(TStompHeaders.NewPersistentHeader(true))); - //if i mod 100 = 0 then - WriteLn('Queued ', i, ' messages in ', sw.ElapsedMilliseconds, ' ms'); + // if i mod 100 = 0 then + WriteLn('Queued ', i, ' messages in ', sw.ElapsedMilliseconds, ' ms'); end; WriteLn('Finished Queueing... Currently Queued ', MSG, ' messages in ', sw.ElapsedMilliseconds, ' ms'); diff --git a/test/teststompclient.dproj b/test/teststompclient.dproj index 9cb2f265..d24c15f9 100644 --- a/test/teststompclient.dproj +++ b/test/teststompclient.dproj @@ -5,7 +5,7 @@ Debug DCC32 teststompclient.exe - 16.1 + 18.1 Debug True Console @@ -16,6 +16,26 @@ true + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + true Base @@ -31,6 +51,24 @@ Base true + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + true Cfg_2 @@ -42,7 +80,27 @@ Base true + + true + Cfg_3 + true + true + + + true + Cfg_3 + true + true + + + true + Cfg_3 + true + true + + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns teststompclient System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= @@ -50,6 +108,85 @@ ..\lib\synapse;$(DCC_UnitSearchPath) teststompclient.exe + + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png + true + $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png + $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png + android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=auto;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + true + true + true + true + true + $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png + true + Debug + $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png + + + iPhoneAndiPad + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png + $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png + $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png + Debug + true + $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes= + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png + $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png + $(MSBuildProjectName) + + + iPhoneAndiPad + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png + $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png + $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png + Debug + true + $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes= + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png + $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png + $(MSBuildProjectName) + + + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_768x1024.png + iPhoneAndiPad + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_120x120.png + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_1024x768.png + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImagePortrait_1536x2048.png + $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_152x152.png + $(BDS)\bin\Artwork\iOS\iPad\FM_ApplicationIcon_76x76.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_80x80.png + true + $(BDS)\bin\Artwork\iOS\iPhone\FM_SpotlightSearchIcon_40x40.png + $(BDS)\bin\Artwork\iOS\iPad\FM_LaunchImageLandscape_2048x1536.png + $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_80x80.png + $(BDS)\bin\Artwork\iOS\iPhone\FM_ApplicationIcon_60x60.png + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false;UIBackgroundModes= + $(BDS)\bin\Artwork\iOS\iPad\FM_SpotlightSearchIcon_40x40.png + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 1033 @@ -69,6 +206,15 @@ C:\Programmi\CodeGear\RAD Studio\5.0\source\Indy\Indy10\Core;C:\Programmi\CodeGear\RAD Studio\5.0\source\Indy\Indy10\System;$(DCC_ObjPath) C:\Programmi\CodeGear\RAD Studio\5.0\source\Indy\Indy10\Core;C:\Programmi\CodeGear\RAD Studio\5.0\source\Indy\Indy10\System;$(DCC_IncludePath) + + true + + + true + + + true + None false @@ -80,6 +226,15 @@ true true + + true + + + true + + + true + Delphi.Personality.12 VCLApplication @@ -129,11 +284,15 @@ + False + False + False + False False True False - + teststompclient.exe @@ -144,105 +303,32 @@ true + + true - - - 1 - .dylib - - - 0 - .bpl + + + true + + - 1 - .dylib + true - - 1 - .dylib - - - + + + - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - - + Contents\Resources 1 - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - + - res\drawable-normal - 1 - - - - - library\lib\x86 - 1 - - - - - 1 - - - 1 - - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - - - res\drawable-xlarge - 1 - - - - - res\drawable-xhdpi - 1 - - - - - 1 - - + classes 1 @@ -252,111 +338,147 @@ 1 + + + Contents\MacOS + 0 + + + 1 + + library\lib\mips 1 - - - res\drawable - 1 - - - - - 1 - - - 1 - - - 0 - - - - - 1 - .framework - - - 0 - - - - - res\drawable-small - 1 - - - - - - 1 - - - Contents\MacOS - 0 - - - - - classes - 1 - - - - - - 1 - - - 1 - - - - - res\drawable - 1 - - - - - Contents\Resources - 1 - - - - + 1 - + + 1 + + 1 - + + 1 + + + 1 + + + 0 + + + 1 + + 1 library\lib\armeabi-v7a 1 + + 1 + + + 0 1 + .framework + + + + + 1 + + + 1 + + + 1 + + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + + library\lib\armeabi + 1 + + + + + 0 1 + + 1 + - + + + 1 + + + 1 + + + 1 + + + - library\lib\armeabi + res\drawable-normal + 1 + + + + + res\drawable-xhdpi 1 @@ -366,54 +488,21 @@ 1 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - 1 - 1 + + 1 + + + 1 + - + + - res\drawable-ldpi - 1 - - - - - res\values - 1 - - - - - 1 - - - 1 - - - - - res\drawable-mdpi + library\lib\armeabi-v7a 1 @@ -423,17 +512,143 @@ 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\values + 1 + + + + + res\drawable-small + 1 + + + + + res\drawable + 1 + + + + + 1 + + + 1 + + + 1 + + 1 - - - - - + + + res\drawable + 1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 0 + .bpl + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + + + res\drawable-mdpi + 1 + + + + + res\drawable-xlarge + 1 + + + + + res\drawable-ldpi + 1 + + + + + 0 + .dll;.bpl + + + 1 + .dylib + + + + + + + + + 12 @@ -445,21 +660,21 @@ + + Base + Cfg_2 Base - - Cfg_3 - Base - - - Base - Cfg_1 Base + + Cfg_3 + Base + diff --git a/unittest/TestStompClient.dproj b/unittest/TestStompClient.dproj index 55ac1767..151b1549 100644 --- a/unittest/TestStompClient.dproj +++ b/unittest/TestStompClient.dproj @@ -1,124 +1,196 @@ - - - {8E4B2D47-EFD1-4ACD-9821-EF2EE2839C83} - 12.0 - TestStompClient.dpr - Debug - DCC32 - - - true - - - true - Base - true - - - true - Base - true - - - true - TestStompClient.exe - $(BDS)\Source\DUnit\src;$(DCC_UnitSearchPath) - CONSOLE_TESTRUNNER;$(DCC_Define) - . - InstantObjects BDE Design-Time Support (Delphi 2010) - WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias) - true - _D14 - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - - - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - - - - - Delphi.Personality.12 - - - - - False - True - False - - - True - False - 2 - 1 - 0 - 0 - False - False - False - False - False - 1040 - 1252 - - - www.instantobjects.org - InstantObjects - 2.1.0.0 - - - - - InstantObjects - 2.1.0.0 - - - - Hengen OPF Core - Hengen Computing OPF - Hengen ADO Persistence Layer - Hengen IBX Persistence Layer - Hengen OPF GUI Controls - Hengen OPF ObjectListMgr Demo Mediators - Delphi Spring Framework Core Library - Delphi Spring Framework Base Class Library - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - TestStompClient.dpr - - - - DUnit / Delphi Win32 - Console - - - 12 - - + + + {8E4B2D47-EFD1-4ACD-9821-EF2EE2839C83} + 18.1 + TestStompClient.dpr + Debug + DCC32 + VCL + True + Win32 + 1025 + Application + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + CompanyName=www.instantobjects.org;FileDescription=InstantObjects;FileVersion=2.1.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=InstantObjects;ProductVersion=2.1.0.0;Comments= + 2 + TestStompClient + Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;DUnitX;$(DCC_Namespace) + 1 + true + 1040 + true + TestStompClient.exe + $(BDS)\Source\DUnit\src;$(DCC_UnitSearchPath) + CONSOLE_TESTRUNNER;$(DCC_Define) + . + InstantObjects BDE Design-Time Support (Delphi 2010) + true + _D14 + 00400000 + x86 + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + $(BDS)\bin\default_app.manifest + TestStompClient_Icon.ico + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + true + 1033 + true + + + TestStompClient_Icon.ico + $(BDS)\bin\default_app.manifest + true + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + true + true + + + DEBUG;$(DCC_Define) + + + Debug + + + true + true + + + + MainSource + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + + Delphi.Personality.12 + + + + + False + True + False + + + True + False + 2 + 1 + 0 + 0 + False + False + False + False + False + 1040 + 1252 + + + www.instantobjects.org + InstantObjects + 2.1.0.0 + + + + + InstantObjects + 2.1.0.0 + + + + Hengen OPF Core + Hengen Computing OPF + Hengen ADO Persistence Layer + Hengen IBX Persistence Layer + Hengen OPF GUI Controls + Hengen OPF ObjectListMgr Demo Mediators + Delphi Spring Framework Core Library + Delphi Spring Framework Base Class Library + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + TestStompClient.dpr + + + + DUnit / Delphi Win32 + Console + + + + + True + True + False + + + 12 + + + diff --git a/unittest/TestStompClient.res b/unittest/TestStompClient.res index 5d911fee4ff356f1245d330809c1f9076587d2fe..4b47357329928f881c43829dc921189f979c3b26 100644 GIT binary patch delta 1485 zcmbtU-D=!M6rOF|g0@-ezm45O@K_171ZMTWE4kVwrgoEs7@OK8l)ggWp$|~#ZJ(e8XS6FP>rme~1EV=}{=RSK9L=xF3*$AG@7EB* z2%+=yc`?OC3>8Up6G43L*NQ)uTc08{HHo$OcX|EeGhwO~>&><1^HLHarkKuT-9~2d zPxDSgLoKndW>H)DvUy1(;X$oCg zKp47Q{I;kSe=UAd{I_`Tokv9D!y!EsUiajpyL9*SiroKXe!leZXlmu)53?|@SO{Vn zd_M%91KZ2OQ5eA?@Qa(6wQiq?z_I|3UzFq7tueB;V zvxu&eXG5O%;~?oZ>aM6qDyr&*QJ5F67VeB^6{oF{CiifoF1fR}St=xVosfeg!2K=k zL6jV0QOmMHfMel{`7lkBEXP5T;i}B|amaIu2@$v=zVZOJyN~;>JZH` z+r%_{i%=^7qN+9n0D~EU`lGB&2wexib2YYMX@>1Nl#DIr2<*UP#0H%as+*>&>sH_x zw8XyV(e10DO{xdF4F<6c&mm*eG&SN;$0w}qFq4|J4Tk+8&@Jt1a4l$e+J2`^Y!x(O z>c-e1j^%m8HkcZ;naXJAL%=olYHSp@q!)T?DTi(kL`lN)t}J`(SsE9Uum9qpk+irwvhIP RPdUm5`sP#=kFR*E-vF>Ep!om* delta 994 zcmaJ;!EVz)5FNKcLPY@+#Z47x>l(x%ha^ryE+mmcOCb_aRQdyMvZSVo9ql@)0*7$m z#EHlUdPN*L!Y}X%mHGkP5noW=t{pWk2(M<>JM-qvo7wl})Q3qUxn!C(M+ny6?~Pj><^^srmQK?Q#sgNjj$E%? zvLcV?^x@g`JM1xYxVhWhGG7M6j_b$q5#z%3y}D&r^2L0)YTwV7s^v<_GNb$f_uEVe zpEr5?zztYCTr-w(NG_-lm_|Cn@DFQiW_PVpZr7jOaOKfZZgY`ZOSiJQ~C2;Kn2k9jTQk7ZE{$ zLIgnX(`z8w@CeG|&Z(>L+jIkb+rak_-+~FCxFi?=>;md3VCw?m&ILl6p4^#~z-z;b z%7`rRY9!MFuyULZYRqdTx~DKt5$~#~>}!CII0|>^0GZL3yM)^V!l4fG`Zzfql9us-O9YC!W6|JyYxR_H3E$^0;-W$nu|$SU2@YssQ= S79tk9CC{*_JxJ(@pNT&yeamqG