Thrift-1401: JSON-protocol for Delphi XE Libraries
Client: delphi
Patch: Jens Geyer
Adds support for the JSON protocol to the existing Delphi XE libraries.
git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1200538 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/delphi/test/TestServer.pas b/lib/delphi/test/TestServer.pas
index 67cce77..ecaf80d 100644
--- a/lib/delphi/test/TestServer.pas
+++ b/lib/delphi/test/TestServer.pas
@@ -1,52 +1,55 @@
-(*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *)
-
-unit TestServer;
-
-interface
-
-uses
-  SysUtils,
-  Generics.Collections,
-  Thrift.Console,
-  Thrift.Server,
-  Thrift.Transport,
-  Thrift.Collections,
-  Thrift.Utils,
-  Thrift.Test,
-  Thrift,
-  Contnrs;
-
-type
-  TTestServer = class
-  public
-    type
-
-      ITestHandler = interface( TThriftTest.Iface )
-        procedure SetServer( AServer : IServer );
-      end;
-
-      TTestHandlerImpl = class( TInterfacedObject, ITestHandler )
-      private
-        FServer : IServer;
-      protected
-        procedure testVoid();
+(*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *)
+
+unit TestServer;
+
+interface
+
+uses
+  SysUtils,
+  Generics.Collections,
+  Thrift.Console,
+  Thrift.Server,
+  Thrift.Transport,
+  Thrift.Protocol,
+  Thrift.Protocol.JSON,
+  Thrift.Collections,
+  Thrift.Utils,
+  Thrift.Test,
+  Thrift,
+  TestConstants,
+  Contnrs;
+
+type
+  TTestServer = class
+  public
+    type
+
+      ITestHandler = interface( TThriftTest.Iface )
+        procedure SetServer( AServer : IServer );
+      end;
+
+      TTestHandlerImpl = class( TInterfacedObject, ITestHandler )
+      private
+        FServer : IServer;
+      protected
+        procedure testVoid();
         function testString(thing: string): string;
         function testByte(thing: ShortInt): ShortInt;
         function testI32(thing: Integer): Integer;
@@ -66,395 +69,421 @@
         procedure testException(arg: string);
         function testMultiException(arg0: string; arg1: string): IXtruct;
         procedure testOneway(secondsToSleep: Integer);
-
-         procedure testStop;
-
-        procedure SetServer( AServer : IServer );
-      end;
-
-      class procedure Execute( args: array of string);
-  end;
-
-implementation
-
-{ TTestServer.TTestHandlerImpl }
-
-procedure TTestServer.TTestHandlerImpl.SetServer(AServer: IServer);
-begin
-  FServer := AServer;
-end;
-
-function TTestServer.TTestHandlerImpl.testByte(thing: ShortInt): ShortInt;
-begin
-	Console.WriteLine('testByte("' + IntToStr( thing) + '")');
-	Result := thing;
-end;
-
-function TTestServer.TTestHandlerImpl.testDouble(thing: Double): Double;
-begin
-	Console.WriteLine('testDouble("' + FloatToStr( thing ) + '")');
-	Result := thing;
-end;
-
-function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz;
-begin
-	Console.WriteLine('testEnum(' + IntToStr( Integer( thing)) + ')');
-  Result := thing;
-end;
-
-procedure TTestServer.TTestHandlerImpl.testException(arg: string);
-var
-  x : TXception;
-begin
-  Console.WriteLine('testException(' + arg + ')');
-  if ( arg = 'Xception') then
-  begin
-    x := TXception.Create;
-    x.ErrorCode := 1001;
-    x.Message_ := 'This is an Xception';
-    raise x;
-  end;
-end;
-
-function TTestServer.TTestHandlerImpl.testI32(thing: Integer): Integer;
-begin
-	Console.WriteLine('testI32("' + IntToStr( thing) + '")');
-	Result := thing;
-end;
-
-function TTestServer.TTestHandlerImpl.testI64(thing: Int64): Int64;
-begin
-	Console.WriteLine('testI64("' + IntToStr( thing) + '")');
-	Result := thing;
-end;
-
-function TTestServer.TTestHandlerImpl.testInsanity(
-  argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
-var
-  hello, goodbye : IXtruct;
-  crazy : IInsanity;
-  looney : IInsanity;
-  first_map : IThriftDictionary<TNumberz, IInsanity>;
-  second_map : IThriftDictionary<TNumberz, IInsanity>;
-  insane : IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
-
-begin
-
-  Console.WriteLine('testInsanity()');
-  hello := TXtructImpl.Create;
-  hello.String_thing := 'hello';
-  hello.Byte_thing := 2;
-  hello.I32_thing := 2;
-  hello.I64_thing := 2;
-
-  goodbye := TXtructImpl.Create;
-  goodbye.String_thing := 'Goodbye4';
-  goodbye.Byte_thing := 4;
-  goodbye.I32_thing := 4;
-  goodbye.I64_thing := 4;
-
-  crazy := TInsanityImpl.Create;
-	crazy.UserMap := TThriftDictionaryImpl<TNumberz, Int64>.Create;
-	crazy.UserMap.AddOrSetValue( TNumberz.EIGHT, 8);
-	crazy.Xtructs := TThriftListImpl<IXtruct>.Create;
-	crazy.Xtructs.Add(goodbye);
-
-  looney := TInsanityImpl.Create;
-  crazy.UserMap.AddOrSetValue( TNumberz.FIVE, 5);
-	crazy.Xtructs.Add(hello);
-
-  first_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
-  second_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
-
-  first_map.AddOrSetValue( TNumberz.SIX, crazy);
-  first_map.AddOrSetValue( TNumberz.THREE, crazy);
-
-  second_map.AddOrSetValue( TNumberz.SIX, looney);
-
-  insane := TThriftDictionaryImpl<Int64, IThriftDictionary<TNumberz, IInsanity>>.Create;
-
-  insane.AddOrSetValue( 1, first_map);
-  insane.AddOrSetValue( 2, second_map);
-
-  Result := insane;
-end;
-
-function TTestServer.TTestHandlerImpl.testList(
-  thing: IThriftList<Integer>): IThriftList<Integer>;
-var
-  first : Boolean;
-  elem : Integer;
-begin
-  Console.Write('testList({');
-  first := True;
-  for elem in thing do
-  begin
-    if first then
-    begin
-      first := False;
-    end else
-    begin
-      Console.Write(', ');
-    end;
-    Console.Write( IntToStr( elem));
-  end;
-  Console.WriteLine('})');
-  Result := thing;
-end;
-
-function TTestServer.TTestHandlerImpl.testMap(
-  thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
-var
-  first : Boolean;
-  key : Integer;
-begin
-  Console.Write('testMap({');
-  first := True;
-  for key in thing.Keys do
-  begin
-  	if (first) then
-    begin
-      first := false;
-    end else
-    begin
-      Console.Write(', ');
-    end;
-    Console.Write(IntToStr(key) + ' => ' + IntToStr( thing[key]));
-  end;
-	Console.WriteLine('})');
-  Result := thing;
-end;
-
-function TTestServer.TTestHandlerImpl.TestMapMap(
-  hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
-var
-  mapmap : IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
-  pos : IThriftDictionary<Integer, Integer>;
-  neg : IThriftDictionary<Integer, Integer>;
-  i : Integer;
-begin
-  Console.WriteLine('testMapMap(' + IntToStr( hello) + ')');
-  mapmap := TThriftDictionaryImpl<Integer, IThriftDictionary<Integer, Integer>>.Create;
-  pos := TThriftDictionaryImpl<Integer, Integer>.Create;
-  neg := TThriftDictionaryImpl<Integer, Integer>.Create;
-
-  for i := 1 to 4 do
-  begin
-    pos.AddOrSetValue( i, i);
-    neg.AddOrSetValue( -i, -i);
-  end;
-
-  mapmap.AddOrSetValue(4, pos);
-  mapmap.AddOrSetValue( -4, neg);
-
-  Result := mapmap;
-end;
-
-function TTestServer.TTestHandlerImpl.testMulti(arg0: ShortInt; arg1: Integer;
-  arg2: Int64; arg3: IThriftDictionary<SmallInt, string>; arg4: TNumberz;
-  arg5: Int64): IXtruct;
-var
-  hello : IXtruct;
-begin
-  Console.WriteLine('testMulti()');
-  hello := TXtructImpl.Create;
-  hello.String_thing := 'Hello2';
-  hello.Byte_thing := arg0;
-  hello.I32_thing := arg1;
-  hello.I64_thing := arg2;
-  Result := hello;
-end;
-
-function TTestServer.TTestHandlerImpl.testMultiException(arg0,
-  arg1: string): IXtruct;
-var
-  x : TXception;
-  x2 : TXception2;
-begin
-  Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')');
-  if ( arg0 = 'Xception') then
-  begin
-    x := TXception.Create;
-    x.ErrorCode := 1001;
-    x.Message_ := 'This is an Xception';
-    raise x;
-  end else
-  if ( arg0 = 'Xception2') then
-  begin
-    x2 := TXception2.Create;
-    x2.ErrorCode := 2002;
-    x2.Struct_thing := TXtructImpl.Create;
-    x2.Struct_thing.String_thing := 'This is an Xception2';
-    raise x2;
-  end;
-
-  Result := TXtructImpl.Create;
-  Result.String_thing := arg1;
-end;
-
-function TTestServer.TTestHandlerImpl.testNest(thing: IXtruct2): IXtruct2;
-var
-  temp : IXtruct;
-begin
-  temp := thing.Struct_thing;
-	Console.WriteLine('testNest({' +
-				 IntToStr( thing.Byte_thing) + ', {' +
-				 '"' + temp.String_thing + '", ' +
-				 IntToStr( temp.Byte_thing) + ', ' +
-				 IntToStr( temp.I32_thing) + ', ' +
-				 IntToStr( temp.I64_thing) + '}, ' +
-				 IntToStr( temp.I32_thing) + '})');
-  Result := thing;
-end;
-
-procedure TTestServer.TTestHandlerImpl.testOneway(secondsToSleep: Integer);
-begin
-	Console.WriteLine('testOneway(' + IntToStr( secondsToSleep )+ '), sleeping...');
-	Sleep(secondsToSleep * 1000);
-	Console.WriteLine('testOneway finished');
-end;
-
-function TTestServer.TTestHandlerImpl.testSet(
-  thing: IHashSet<Integer>):IHashSet<Integer>;
-var
-  first : Boolean;
-  elem : Integer;
-begin
-  Console.Write('testSet({');
-  first := True;
-
-  for elem in thing do
-  begin
-    if first then
-    begin
-      first := False;
-    end else
-    begin
-      Console.Write( ', ');
-    end;
-    Console.Write( IntToStr( elem));
-  end;
-  Console.WriteLine('})');
-  Result := thing;
-end;
-
-procedure TTestServer.TTestHandlerImpl.testStop;
-begin
-  if FServer <> nil then
-  begin
-    FServer.Stop;
-  end;
-end;
-
-function TTestServer.TTestHandlerImpl.testString(thing: string): string;
-begin
-	Console.WriteLine('teststring("' + thing + '")');
-	Result := thing;
-end;
-
-function TTestServer.TTestHandlerImpl.testStringMap(
-  thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
-begin
-
-end;
-
-function TTestServer.TTestHandlerImpl.testTypedef(thing: Int64): Int64;
-begin
-	Console.WriteLine('testTypedef(' + IntToStr( thing) + ')');
-  Result := thing;
-end;
-
-procedure TTestServer.TTestHandlerImpl.TestVoid;
-begin
-  Console.WriteLine('testVoid()');
-end;
-
-function TTestServer.TTestHandlerImpl.testStruct(thing: IXtruct): IXtruct;
-begin
-  Console.WriteLine('testStruct({' +
-    '"' + thing.String_thing + '", ' +
-		  IntToStr( thing.Byte_thing) + ', ' +
-			IntToStr( thing.I32_thing) + ', ' +
-			IntToStr( thing.I64_thing));
-  Result := thing;
-end;
-
-{ TTestServer }
-
-class procedure TTestServer.Execute(args: array of string);
-var
-  UseBufferedSockets : Boolean;
-  UseFramed : Boolean;
-  Port : Integer;
-  testHandler : ITestHandler;
-  testProcessor : IProcessor;
-  ServerSocket : IServerTransport;
-  ServerEngine : IServer;
-  TransportFactroy : ITransportFactory;
-
-
-begin
-  try
-    UseBufferedSockets := False;
-    UseFramed := False;
-    Port := 9090;
-
-    if ( Length( args) > 0) then
-    begin
-      Port :=  StrToIntDef( args[0], Port);
-
-      if ( Length( args) > 0) then
-      begin
-        if ( args[0] = 'raw' ) then
-        begin
-          // as default
-        end else
-        if ( args[0] = 'buffered' ) then
-        begin
-          UseBufferedSockets := True;
-        end else
-        if ( args[0] = 'framed' ) then
-        begin
-          UseFramed := True;
-        end else
-        begin
-          // Fall back to the older boolean syntax
-          UseBufferedSockets := StrToBoolDef( args[1], UseBufferedSockets);
-        end
-      end
-    end;
-
-    testHandler := TTestHandlerImpl.Create;
-
-    testProcessor := TThriftTest.TProcessorImpl.Create( testHandler );
-    ServerSocket := TServerSocketImpl.Create( Port, 0, UseBufferedSockets );
-    if UseFramed then
-    begin
-      TransportFactroy := TFramedTransportImpl.TFactory.Create;
-      ServerEngine := TSimpleServer.Create( testProcessor, ServerSocket,
-         TransportFactroy);
-    end else
-    begin
-      ServerEngine := TSimpleServer.Create( testProcessor, ServerSocket);
-    end;
-
-    testHandler.SetServer( ServerEngine);
-
-    Console.WriteLine('Starting the server on port ' + IntToStr( Port) +
-      IfValue(UseBufferedSockets, ' with buffered socket', '') +
-      IfValue(useFramed, ' with framed transport', '') +
-      '...');
-
-    serverEngine.Serve;
-    testHandler.SetServer( nil);
-
-  except
-    on E: Exception do
-    begin
-      Console.Write( E.Message);
-    end;
-  end;
-  Console.WriteLine( 'done.');
-end;
-
-end.
+
+         procedure testStop;
+
+        procedure SetServer( AServer : IServer );
+      end;
+
+      class procedure Execute( args: array of string);
+  end;
+
+implementation
+
+{ TTestServer.TTestHandlerImpl }
+
+procedure TTestServer.TTestHandlerImpl.SetServer(AServer: IServer);
+begin
+  FServer := AServer;
+end;
+
+function TTestServer.TTestHandlerImpl.testByte(thing: ShortInt): ShortInt;
+begin
+  Console.WriteLine('testByte("' + IntToStr( thing) + '")');
+  Result := thing;
+end;
+
+function TTestServer.TTestHandlerImpl.testDouble(thing: Double): Double;
+begin
+  Console.WriteLine('testDouble("' + FloatToStr( thing ) + '")');
+  Result := thing;
+end;
+
+function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz;
+begin
+  Console.WriteLine('testEnum(' + IntToStr( Integer( thing)) + ')');
+  Result := thing;
+end;
+
+procedure TTestServer.TTestHandlerImpl.testException(arg: string);
+var
+  x : TXception;
+begin
+  Console.WriteLine('testException(' + arg + ')');
+  if ( arg = 'Xception') then
+  begin
+    x := TXception.Create;
+    x.ErrorCode := 1001;
+    x.Message_ := 'This is an Xception';
+    raise x;
+  end;
+end;
+
+function TTestServer.TTestHandlerImpl.testI32(thing: Integer): Integer;
+begin
+  Console.WriteLine('testI32("' + IntToStr( thing) + '")');
+  Result := thing;
+end;
+
+function TTestServer.TTestHandlerImpl.testI64(thing: Int64): Int64;
+begin
+  Console.WriteLine('testI64("' + IntToStr( thing) + '")');
+  Result := thing;
+end;
+
+function TTestServer.TTestHandlerImpl.testInsanity(
+  argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
+var
+  hello, goodbye : IXtruct;
+  crazy : IInsanity;
+  looney : IInsanity;
+  first_map : IThriftDictionary<TNumberz, IInsanity>;
+  second_map : IThriftDictionary<TNumberz, IInsanity>;
+  insane : IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
+
+begin
+
+  Console.WriteLine('testInsanity()');
+  hello := TXtructImpl.Create;
+  hello.String_thing := 'hello';
+  hello.Byte_thing := 2;
+  hello.I32_thing := 2;
+  hello.I64_thing := 2;
+
+  goodbye := TXtructImpl.Create;
+  goodbye.String_thing := 'Goodbye4';
+  goodbye.Byte_thing := 4;
+  goodbye.I32_thing := 4;
+  goodbye.I64_thing := 4;
+
+  crazy := TInsanityImpl.Create;
+  crazy.UserMap := TThriftDictionaryImpl<TNumberz, Int64>.Create;
+  crazy.UserMap.AddOrSetValue( TNumberz.EIGHT, 8);
+  crazy.Xtructs := TThriftListImpl<IXtruct>.Create;
+  crazy.Xtructs.Add(goodbye);
+
+  looney := TInsanityImpl.Create;
+  crazy.UserMap.AddOrSetValue( TNumberz.FIVE, 5);
+  crazy.Xtructs.Add(hello);
+
+  first_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
+  second_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
+
+  first_map.AddOrSetValue( TNumberz.SIX, crazy);
+  first_map.AddOrSetValue( TNumberz.THREE, crazy);
+
+  second_map.AddOrSetValue( TNumberz.SIX, looney);
+
+  insane := TThriftDictionaryImpl<Int64, IThriftDictionary<TNumberz, IInsanity>>.Create;
+
+  insane.AddOrSetValue( 1, first_map);
+  insane.AddOrSetValue( 2, second_map);
+
+  Result := insane;
+end;
+
+function TTestServer.TTestHandlerImpl.testList(
+  thing: IThriftList<Integer>): IThriftList<Integer>;
+var
+  first : Boolean;
+  elem : Integer;
+begin
+  Console.Write('testList({');
+  first := True;
+  for elem in thing do
+  begin
+    if first then
+    begin
+      first := False;
+    end else
+    begin
+      Console.Write(', ');
+    end;
+    Console.Write( IntToStr( elem));
+  end;
+  Console.WriteLine('})');
+  Result := thing;
+end;
+
+function TTestServer.TTestHandlerImpl.testMap(
+  thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
+var
+  first : Boolean;
+  key : Integer;
+begin
+  Console.Write('testMap({');
+  first := True;
+  for key in thing.Keys do
+  begin
+    if (first) then
+    begin
+      first := false;
+    end else
+    begin
+      Console.Write(', ');
+    end;
+    Console.Write(IntToStr(key) + ' => ' + IntToStr( thing[key]));
+  end;
+  Console.WriteLine('})');
+  Result := thing;
+end;
+
+function TTestServer.TTestHandlerImpl.TestMapMap(
+  hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
+var
+  mapmap : IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
+  pos : IThriftDictionary<Integer, Integer>;
+  neg : IThriftDictionary<Integer, Integer>;
+  i : Integer;
+begin
+  Console.WriteLine('testMapMap(' + IntToStr( hello) + ')');
+  mapmap := TThriftDictionaryImpl<Integer, IThriftDictionary<Integer, Integer>>.Create;
+  pos := TThriftDictionaryImpl<Integer, Integer>.Create;
+  neg := TThriftDictionaryImpl<Integer, Integer>.Create;
+
+  for i := 1 to 4 do
+  begin
+    pos.AddOrSetValue( i, i);
+    neg.AddOrSetValue( -i, -i);
+  end;
+
+  mapmap.AddOrSetValue(4, pos);
+  mapmap.AddOrSetValue( -4, neg);
+
+  Result := mapmap;
+end;
+
+function TTestServer.TTestHandlerImpl.testMulti(arg0: ShortInt; arg1: Integer;
+  arg2: Int64; arg3: IThriftDictionary<SmallInt, string>; arg4: TNumberz;
+  arg5: Int64): IXtruct;
+var
+  hello : IXtruct;
+begin
+  Console.WriteLine('testMulti()');
+  hello := TXtructImpl.Create;
+  hello.String_thing := 'Hello2';
+  hello.Byte_thing := arg0;
+  hello.I32_thing := arg1;
+  hello.I64_thing := arg2;
+  Result := hello;
+end;
+
+function TTestServer.TTestHandlerImpl.testMultiException(arg0,
+  arg1: string): IXtruct;
+var
+  x : TXception;
+  x2 : TXception2;
+begin
+  Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')');
+  if ( arg0 = 'Xception') then
+  begin
+    x := TXception.Create;
+    x.ErrorCode := 1001;
+    x.Message_ := 'This is an Xception';
+    raise x;
+  end else
+  if ( arg0 = 'Xception2') then
+  begin
+    x2 := TXception2.Create;
+    x2.ErrorCode := 2002;
+    x2.Struct_thing := TXtructImpl.Create;
+    x2.Struct_thing.String_thing := 'This is an Xception2';
+    raise x2;
+  end;
+
+  Result := TXtructImpl.Create;
+  Result.String_thing := arg1;
+end;
+
+function TTestServer.TTestHandlerImpl.testNest(thing: IXtruct2): IXtruct2;
+var
+  temp : IXtruct;
+begin
+  temp := thing.Struct_thing;
+  Console.WriteLine('testNest({' +
+         IntToStr( thing.Byte_thing) + ', {' +
+         '"' + temp.String_thing + '", ' +
+         IntToStr( temp.Byte_thing) + ', ' +
+         IntToStr( temp.I32_thing) + ', ' +
+         IntToStr( temp.I64_thing) + '}, ' +
+         IntToStr( temp.I32_thing) + '})');
+  Result := thing;
+end;
+
+procedure TTestServer.TTestHandlerImpl.testOneway(secondsToSleep: Integer);
+begin
+  Console.WriteLine('testOneway(' + IntToStr( secondsToSleep )+ '), sleeping...');
+  Sleep(secondsToSleep * 1000);
+  Console.WriteLine('testOneway finished');
+end;
+
+function TTestServer.TTestHandlerImpl.testSet(
+  thing: IHashSet<Integer>):IHashSet<Integer>;
+var
+  first : Boolean;
+  elem : Integer;
+begin
+  Console.Write('testSet({');
+  first := True;
+
+  for elem in thing do
+  begin
+    if first then
+    begin
+      first := False;
+    end else
+    begin
+      Console.Write( ', ');
+    end;
+    Console.Write( IntToStr( elem));
+  end;
+  Console.WriteLine('})');
+  Result := thing;
+end;
+
+procedure TTestServer.TTestHandlerImpl.testStop;
+begin
+  if FServer <> nil then
+  begin
+    FServer.Stop;
+  end;
+end;
+
+function TTestServer.TTestHandlerImpl.testString(thing: string): string;
+begin
+  Console.WriteLine('teststring("' + thing + '")');
+  Result := thing;
+end;
+
+function TTestServer.TTestHandlerImpl.testStringMap(
+  thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
+begin
+
+end;
+
+function TTestServer.TTestHandlerImpl.testTypedef(thing: Int64): Int64;
+begin
+  Console.WriteLine('testTypedef(' + IntToStr( thing) + ')');
+  Result := thing;
+end;
+
+procedure TTestServer.TTestHandlerImpl.TestVoid;
+begin
+  Console.WriteLine('testVoid()');
+end;
+
+function TTestServer.TTestHandlerImpl.testStruct(thing: IXtruct): IXtruct;
+begin
+  Console.WriteLine('testStruct({' +
+    '"' + thing.String_thing + '", ' +
+      IntToStr( thing.Byte_thing) + ', ' +
+      IntToStr( thing.I32_thing) + ', ' +
+      IntToStr( thing.I64_thing));
+  Result := thing;
+end;
+
+{ TTestServer }
+
+class procedure TTestServer.Execute(args: array of string);
+var
+  UseBufferedSockets : Boolean;
+  UseFramed : Boolean;
+  Port : Integer;
+  testHandler : ITestHandler;
+  testProcessor : IProcessor;
+  ServerSocket : IServerTransport;
+  ServerEngine : IServer;
+  TransportFactory : ITransportFactory;
+  ProtocolFactory : IProtocolFactory;
+  i : Integer;
+  s : string;
+  protType, p : TKnownProtocol;
+begin
+  try
+    UseBufferedSockets := False;
+    UseFramed := False;
+    protType := prot_Binary;
+    Port := 9090;
+
+    i := 0;
+    while ( i < Length(args) ) do begin
+      s := args[i];
+      Inc(i);
+
+      if StrToIntDef( s, -1) > 0 then
+      begin
+        Port :=  StrToIntDef( s, Port);
+      end else
+      if ( s = 'raw' ) then
+      begin
+        // as default
+      end else
+      if ( s = 'buffered' ) then
+      begin
+        UseBufferedSockets := True;
+      end else
+      if ( s = 'framed' ) then
+      begin
+        UseFramed := True;
+      end else
+      if (s = '-prot') then  // -prot JSON|binary
+      begin
+        s := args[i];
+        Inc( i );
+        for p:= Low(TKnownProtocol) to High(TKnownProtocol) do begin
+          if SameText( s, KNOWN_PROTOCOLS[p]) then begin
+            protType := p;
+            Break;
+          end;
+        end;
+      end else
+      begin
+        // Fall back to the older boolean syntax
+        UseBufferedSockets := StrToBoolDef( args[1], UseBufferedSockets);
+      end
+    end;
+
+    // create protocol factory, default to BinaryProtocol
+    case protType of
+      prot_Binary:  ProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
+      prot_JSON  :  ProtocolFactory := TJSONProtocolImpl.TFactory.Create;
+    else
+      ASSERT( FALSE);  // unhandled case!
+      ProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
+    end;
+
+    testHandler := TTestHandlerImpl.Create;
+
+    testProcessor := TThriftTest.TProcessorImpl.Create( testHandler );
+    ServerSocket := TServerSocketImpl.Create( Port, 0, UseBufferedSockets );
+
+    if UseFramed
+    then TransportFactory := TFramedTransportImpl.TFactory.Create
+    else TransportFactory := TTransportFactoryImpl.Create;
+
+    ServerEngine := TSimpleServer.Create( testProcessor,
+                                          ServerSocket,
+                                          TransportFactory,
+                                          ProtocolFactory);
+
+    testHandler.SetServer( ServerEngine);
+
+    Console.WriteLine('Starting the server on port ' + IntToStr( Port) +
+      IfValue(UseBufferedSockets, ' with buffered socket', '') +
+      IfValue(useFramed, ' with framed transport', '') +
+      ' using '+KNOWN_PROTOCOLS[protType]+' protocol' +
+      '...');
+
+    serverEngine.Serve;
+    testHandler.SetServer( nil);
+
+  except
+    on E: Exception do
+    begin
+      Console.Write( E.Message);
+    end;
+  end;
+  Console.WriteLine( 'done.');
+end;
+
+end.