Merge branch '0.12.1'
diff --git a/.flake8 b/.flake8
new file mode 100644
index 0000000..df8fdb2
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,5 @@
+[flake8]
+exclude = .git,__pycache__,**/gen-*/**,contrib/**,docs/source/conf.py,old,build,dist
+ignore = W504,E402,E501
+max-complexity = 30
+max-line-length = 120
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..edd7bef
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,15 @@
+<!-- Explain the changes in the pull request below: -->
+
+
+<!-- We recommend you review the checklist before submitting a pull request. -->
+
+- [ ] Did you create an [Apache Jira](https://issues.apache.org/jira/projects/THRIFT/issues/) ticket? (not required for trivial changes)
+- [ ] Does your pull request title follow the pattern "THRIFT-NNNN: describe my issue"? (not required for trivial changes)
+- [ ] Did you squash your changes to a single commit?
+- [ ] Did you do your best to avoid breaking changes? If one was needed, did you label the Jira ticket with "Breaking-Change"
+
+<!--
+ The Contributing Guide at:
+ https://github.com/apache/thrift/blob/master/CONTRIBUTING.md
+ has more details and tips for committing properly.
+-->
diff --git a/.gitignore b/.gitignore
index 4873d98..fb7651e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -198,6 +198,7 @@
/lib/d/test/transport_test
/lib/d/unittest/
/lib/dart/coverage
+/lib/dart/**/.dart_tool
/lib/dart/**/.packages
/lib/dart/**/packages
/lib/dart/**/.pub/
@@ -210,15 +211,18 @@
/lib/delphi/**/*.2007
/lib/delphi/**/*.dproj
/lib/delphi/**/codegen/*.bat
+/lib/erl/_build/
/lib/erl/.eunit
/lib/erl/.generated
/lib/erl/.rebar/
-/lib/erl/deps/
+/lib/erl/_build/
/lib/erl/ebin
+/lib/erl/rebar.lock
/lib/erl/src/thrift.app.src
/lib/erl/test/*.beam
/lib/erl/test/*.hrl
/lib/erl/test/Thrift_omit_without.thrift
+/lib/erl/rebar.lock
/lib/haxe/test/bin
/lib/haxe/test/data.tmp
/lib/hs/dist
@@ -231,6 +235,8 @@
/lib/js/test/build
/lib/netcore/**/bin
/lib/netcore/**/obj
+/lib/netstd/**/bin
+/lib/netstd/**/obj
/lib/nodejs/coverage
/lib/nodejs/node_modules/
/lib/perl/MANIFEST
@@ -287,6 +293,7 @@
/lib/rs/test/src/ultimate.rs
/lib/rs/*.iml
/lib/rs/**/*.iml
+/lib/swift/.build
/libtool
/ltmain.sh
/missing
@@ -306,6 +313,7 @@
/test/cpp/TestServer
/test/csharp/obj
/test/csharp/bin
+/test/dart/**/.dart_tool
/test/dart/**/.packages
/test/dart/**/packages
/test/dart/**/.pub/
@@ -334,6 +342,9 @@
/test/netcore/**/bin
/test/netcore/**/obj
/test/netcore/Thrift
+/test/netstd/**/bin
+/test/netstd/**/obj
+/test/netstd/Thrift
/test/php/php_ext_dir/
/test/rs/Cargo.lock
/test/rs/src/thrift_test.rs
@@ -387,6 +398,9 @@
/tutorial/netcore/**/bin
/tutorial/netcore/**/obj
/tutorial/netcore/Thrift
+/tutorial/netstd/**/bin
+/tutorial/netstd/**/obj
+/tutorial/netstd/Interfaces
/tutorial/rs/*.iml
/tutorial/rs/src/shared.rs
/tutorial/rs/src/tutorial.rs
diff --git a/.travis.yml b/.travis.yml
index 54ebe00..4a399a6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -68,18 +68,8 @@
# ========================= stage: thrift =======================
# ------------------------- phase: cross ------------------------
- # apache/thrift official PR builds can exceed 50 minutes per job so combine all cross tests
- stage: thrift
script: build/docker/run.sh
- if: repo = apache/thrift
- env:
- - JOB="Cross Language Tests"
- - SCRIPT="cross-test.sh"
-
- # fork based PR builds cannot exceed 50 minutes per job
- - stage: thrift
- script: build/docker/run.sh
- if: repo != apache/thrift
env:
- JOB="Cross Language Tests (Binary Protocol)"
- SCRIPT="cross-test.sh"
@@ -87,7 +77,6 @@
- stage: thrift
script: build/docker/run.sh
- if: repo != apache/thrift
env:
- JOB="Cross Language Tests (Header, JSON Protocols)"
- SCRIPT="cross-test.sh"
@@ -95,7 +84,6 @@
- stage: thrift
script: build/docker/run.sh
- if: repo != apache/thrift
env:
- JOB="Cross Language Tests (Compact and Multiplexed Protocols)"
- SCRIPT="cross-test.sh"
@@ -142,23 +130,6 @@
- JOB="CMake"
- BUILD_ARG="-DCMAKE_BUILD_TYPE=Release"
- # C++ specific options: compiler plug-in, threading model
- - script: build/docker/run.sh
- env:
- - JOB="C++98 (Boost Thread)"
- - SCRIPT="cmake.sh"
- - BUILD_LIBS="CPP TESTING TUTORIALS"
- - BUILD_ARG="-DCMAKE_CXX_STANDARD=98 -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCMAKE_CXX_EXTENSIONS=OFF --DWITH_BOOSTTHREADS=ON -DWITH_PYTHON=OFF -DWITH_C_GLIB=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF"
- - BUILD_ENV="-e CC=clang -e CXX=clang++"
-
- - script: build/docker/run.sh
- env:
- - JOB="C++ (Std Thread) and Plugin"
- - SCRIPT="cmake.sh"
- - BUILD_LIBS="CPP TESTING TUTORIALS"
- - BUILD_ARG="-DWITH_PLUGIN=ON -DWITH_STDTHREADS=ON -DWITH_PYTHON=OFF -DWITH_C_GLIB=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF"
- - BUILD_ENV="-e CC=clang -e CXX=clang++"
-
# ------------------------- phase: dist -------------------------
- script: build/docker/run.sh
env:
diff --git a/ApacheThrift.nuspec b/ApacheThrift.nuspec
new file mode 100644
index 0000000..8ed9236
--- /dev/null
+++ b/ApacheThrift.nuspec
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+
+<!--
+ Licensed 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.
+
+ Instructions for building a nuget package:
+
+ 1. Open Thrift.sln in lib\csharp\src and build the release version
+ of the "Thrift" and "Thrift.45" projects.
+ 2. Open Thrift.sln in lib\netcore and build the release version of
+ the "Thrift" project.
+ 3. nuget setApiKey <your-api-key>
+ 3. nuget pack ApacheThrift.nuspec -Symbols -SymbolPackageFormat snupkg
+ 4. nuget push ApacheThrift.0.13.0.nupkg -Source https://api.nuget.org/v3/index.json
+ -->
+
+<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
+ <metadata>
+ <id>ApacheThrift</id>
+ <version>0.13.0</version>
+ <title>Apache Thrift 0.13.0</title>
+ <authors>Apache Thrift Developers</authors>
+ <owners>Apache Software Foundation</owners>
+ <license type="expression">Apache-2.0</license>
+ <projectUrl>http://thrift.apache.org/</projectUrl>
+ <requireLicenseAcceptance>true</requireLicenseAcceptance>
+ <summary>Apache Thrift .NET Library</summary>
+ <description>
+ Contains runtime libraries from lib/csharp for net35 and net45 frameworks,
+ and from lib/netcore for netstandard2.0 framework development.
+ </description>
+ <repository type="GitHub" url="https://github.com/apache/thrift" branch="release/0.13.0" />
+ <tags>Apache Thrift RPC</tags>
+ </metadata>
+ <files>
+ <file src="lib\csharp\src\bin\Release\Thrift.*" target="lib\net35" />
+ <file src="lib\csharp\src\bin\Release\Thrift45.*" target="lib\net45" />
+ <file src="lib\netcore\Thrift\bin\Release\netstandard2.0\*.*" target="lib\netstandard2.0" />
+ </files>
+</package>
\ No newline at end of file
diff --git a/CHANGES b/CHANGES
deleted file mode 100644
index 51d6b64..0000000
--- a/CHANGES
+++ /dev/null
@@ -1,2928 +0,0 @@
-Apache Thrift Changelog
-
-================================================================================
-Thrift 0.12.1
---------------------------------------------------------------------------------
-
-## Bug fixes
- * [THRIFT-4024] - Skip() should throw on unknown data types
- * [THRIFT-4783] - Thrift should throw when skipping over unexpected data
- * [THRIFT-4784] - Thrift should throw when skipping over unexpected data
- * additional test for TSimpleJSONProtocol
- * [THRIFT-4698] - add haskell hackage sdist target and fix cabal file
- * [THRIFT-4750] - as3 changes to build and publish to maven central
- * [THRIFT-4746] - changes for publishing to maven; fix java debug vs. release build with cmake
- * [THRIFT-4691] - ensure CPAN module runs unit tests
-
-
-================================================================================
-Thrift 0.12.0
---------------------------------------------------------------------------------
-## New Languages
- * Common LISP (cl)
- * Swift
- * Typescript (nodets)
-
-## Deprecated Languages
- * Cocoa
-
-## Breaking Changes (since 0.11.0)
- * [THRIFT-4529] - Rust enum variants are now camel-cased instead of uppercased to conform to Rust naming conventions
- * [THRIFT-4448] - Support for golang 1.6 and earlier has been dropped.
- * [THRIFT-4474] - PHP now uses the PSR-4 loader by default instead of class maps.
- * [THRIFT-4532] - method signatures changed in the compiler's t_oop_generator.
- * [THRIFT-4648] - The C (GLib) compiler's handling of namespaces has been improved.
-
-## Known Issues (Blocker or Critical)
- * [THRIFT-4037] - build: use a single build system for thrift
- * [THRIFT-4119] - build: bootstrap.sh is missing from source tarball
- * [THRIFT-3289] - csharp: socket exhaustion in csharp implementation
- * [THRIFT-3029] - cocoa: Getters for fields defined with uppercase names do not work
- * [THRIFT-3325] - cocoa: Extended services aren't subclasses in generated Cocoa
- * [THRIFT-4116] - cocoa: Thrift de-capitalizes the name of IsSet property in Cocoa
- * [THRIFT-3877] - cpp: the http implementation is not standard; interop with other languages is spotty at best
- * [THRIFT-4180] - cpp: Impossible to build Thrift C++ library for Android (NDK)
- * [THRIFT-4384] - cpp: Using multiple async services simultaneously is not thread-safe
- * [THRIFT-3108] - haskell: Defaulted struct parameters on a service generates invalid Haskell
- * [THRIFT-3990] - nodejs: Exception swallowed by deserialization function
- * [THRIFT-4214] - nodejs: map<i64,value> key treated as hex value in JavaScript
- * [THRIFT-4602] - nodejs: ERROR in ./node_modules/thrift/lib/nodejs/lib/thrift/connection.js Module not found: Error: Can't resolve 'child_process'
- * [THRIFT-4639] - nodejs: Sequence numbering for multiplexed protocol broken
- * [THRIFT-1310] - php: sequence and reconnection management issues
- * [THRIFT-1538] - php: Error during deserialization int64 on 32-bit architecture
- * [THRIFT-1580] - php: thrift type i64 java to php serialize/deserealize not working
- * [THRIFT-1950] - php: PHP gets stuck in infinite loop
- * [THRIFT-2954] - python: sending int or float in a double field breaks the connection
- * [THRIFT-4080] - python: unix sockets can get stuck forever
- * [THRIFT-4281] - python: generated code is out of order and causes load issues
- * [THRIFT-4677] - py3: UnicodeDecideError in Python3
-
-## Build Process
- * [THRIFT-4308] - D language docker images need demios for libevent and openssl fixed to re-enable make cross on dlang
- * [THRIFT-4579] - Use Ubuntu Bionic (18.04 LTS) for CI builds instead of Artful (17.10)
- * [THRIFT-4508] - Define CI operating system coverage rules for the project and (hopefully) simplify CI a little more
- * [THRIFT-4397] - ubuntu install instructions broken on 16.04
- * [THRIFT-4545] - Appveyor builds are failing due to a haskell / cabal update in chocolatey
- * [THRIFT-4452] - optimize Dockerfile (only onetime apt-get update)
- * [THRIFT-4440] - rm `build/docker/ubuntu-trusty/Dockerfile.orig`
- * [THRIFT-4352] - Ubuntu Artful doesn't appear to be compatible with Thrift and Haxe 3.4.2
- * [THRIFT-4666] - DLang Client Pool Test fails sporadically
- * [THRIFT-4676] - CL tutorial build fails sporadically
- * [THRIFT-4456] - Make haxelib download quiet so it doesn't blow up the build log
- * [THRIFT-4605] - bootstrap.sh fails if automake=1.16.1
-
-## c_glib
- * [THRIFT-4648] - The C (GLib) compiler's handling of namespaces has been improved.
- * [THRIFT-4622] - glibC compilation issue
- * [THRIFT-4671] - c glib is unable to handle client close unexpectedly
-
-## cl (new language support in 0.12.0)
- * [THRIFT-82] - Common Lisp support
-
-## csharp
- * [THRIFT-4558] - reserved Csharp keywords are not escaped in some cases
- * [THRIFT-4637] - C# async mode generates incorrect code with inherited services
- * [THRIFT-4672] - IAsyncResult style methods not being supported by certain transports leads to issues in mixed ISync/IAsync use cases
- * [THRIFT-4539] - Allow TBufferedTransport to be used as base class
- * [THRIFT-4535] - XML docs; code cleanup (tabs->spaces; String->string)
- * [THRIFT-4492] - protected ExceptionType type member of TApplicationException cannot be accessed
- * [THRIFT-4446] - JSONProtocol Base64 Encoding Trims Padding
- * [THRIFT-4455] - Missing dispose calls in ThreadedServer & ThreadpoolServer
- * [THRIFT-4609] - keep InnerException wherever appropriate
- * [THRIFT-4673] - IAsyncResult not supported by layered transports (buffered/framed)
-
-## cpp
- * [THRIFT-4476] - Typecasting problem on list items
- * [THRIFT-4465] - TNonblockingServer throwing THRIFT LOGGER: TConnection::workSocket(): THRIFT_EAGAIN (unavailable resources)
- * [THRIFT-4680] - TBufferTransports.h does not compile under Visual Studio 2017
- * [THRIFT-4618] - TNonblockingServer crash because of limitation of select()
- * [THRIFT-4620] - TZlibTransport.cpp doesn't ensure that there is enough space for the zlib flush marker in the buffer.
- * [THRIFT-4571] - ZeroMQ contrib library needs a refresh
- * [THRIFT-4559] - TSSLServerSocket incorrectly prints errors
- * [THRIFT-4578] - Move `TAsyncProtocolProcessor` into main thrift library
- * [THRIFT-4418] - evhttp_connection_new is deprecated; use evhttp_connection_base_new
-
-## compiler
- * [THRIFT-4644] - Compiler cannot be compiled on macOS(maybe also on other platforms with clang)
- * [THRIFT-4531] - Thrift generates wrong Python code for immutable structures with optional members
- * [THRIFT-4513] - thrift generated code is not stable for constants
- * [THRIFT-4532] - Avoid updating Thrift compiler generated code if the output has not changed
- * [THRIFT-4400] - Visual Studio Compiler project should link runtime statically in release builds
- * [THRIFT-4399] - plugin.thrift t_const_value is not used as a union in C++ code -- fix this
- * [THRIFT-4496] - Dealing with language keywords in Thrift (e.g. service method names)
- * [THRIFT-4393] - repeated runs of compiler produce different binary output at plugin interface
-
-## dlang
- * [THRIFT-4478] - Thrift will not build with dlang 2.078 or later
- * [THRIFT-4503] - dlang servers logError on normal client disconnection
- * [THRIFT-4308] - D language docker images need demios for libevent and openssl fixed to re-enable make cross on dlang
-
-## dart
- * [THRIFT-4646] - Effective Dart and Exceptions
- * [THRIFT-4439] - Shouldn't download dart.deb directly.
-
-## delphi
- * [THRIFT-4562] - Calling wrong exception CTOR leads to "call failed: unknown result" instead of the real exception being thrown
- * [THRIFT-4554] - uncompileable code with member names that are also types under specific conditions
- * [THRIFT-4422] - Add Async implementation via IFuture
- * [THRIFT-4485] - Possible invalid ptr AV with overlapped read/write on pipes
- * [THRIFT-4549] - Thrift exceptions should derive from TException
- * [THRIFT-4540] - buffered transport broken when trying to re-open a formerly closed transport
- * [THRIFT-4473] - Move Thrift.Console.pas out of the Library
- * [THRIFT-4490] - Allow a default service as fallback for multiplex processors connected by old clients
- * [THRIFT-4454] - Large writes/reads may cause range check errors in debug mode
- * [THRIFT-4461] - Compiler directive should match Delphi XE4
- * [THRIFT-4462] - First line in Console duplicated
- * [THRIFT-4642] - FPU ctrl word settings may cause an unexpected "denormalized" error
-
-## erlang
- * [THRIFT-4497] - Erlang records should use map() for map type
- * [THRIFT-4495] - Erlang records should allow 'undefined' for non-required fields
- * [THRIFT-4580] - Fix erlang tutorial unpack on Windows
- * [THRIFT-4582] - Ubuntu Xenial erlang 18.3 "make check" fails
-
-## golang
- * [THRIFT-4448] - Support for golang 1.6 and earlier has been dropped.
- * [THRIFT-4253] - Go generator assigns strings to field in const instead of pointers.
- * [THRIFT-4573] - Unions Field Count Does Not Consider Binary
- * [THRIFT-4447] - Golang: Panic on p.c.Call when using deprecated initializers
- * [THRIFT-4650] - Required field incorrectly marked as set when fieldType does not match
- * [THRIFT-4486] - Golang: -remote.go client cleanup
- * [THRIFT-4537] - TSimpleServer can exit Accept loop with lock still acquired
- * [THRIFT-4516] - Add support for go 1.10
- * [THRIFT-4421] - golang tests rely on gomock, which has change behaviour, causing tests to fail
- * [THRIFT-4626] - Communication crash when using binary/compact protocol and zlib transport
- * [THRIFT-4659] - golang race detected when closing listener socket
-
-## haskell
- * [THRIFT-4634] - Haskell builds with older cabal cannot reconcile complex version requirements
-
-## java
- * [THRIFT-4259] - Thrift does not compile due to Ant Maven task errors
- * [THRIFT-1418] - Compiling Thrift from source: Class org.apache.tools.ant.taskdefs.ConditionTask doesn't support the nested "typefound" element
- * [THRIFT-4530] - proposal: add nullability annotations to generated Java code
- * [THRIFT-4614] - Generate missing @Nullable annotations for Java iterator getters
- * [THRIFT-4555] - Getter of binary field in Java creates unnecessary copy
- * [THRIFT-3983] - libthrift is deployed on central with pom packaging instead of jar
- * [THRIFT-4294] - Java Configure Fails for Ant >= 1.10
- * [THRIFT-4178] - Java libraries missing from package when using cmake
- * [THRIFT-4120] - pom files are not generated or provided in the build
- * [THRIFT-1507] - Maven can't download resource from central when behind a proxy and won't use local repository
- * [THRIFT-4556] - Optional rethrow of unhandled exceptions in java processor
- * [THRIFT-4337] - Able to set keyStore and trustStore as InputStream in the TSSLTransportFactory.TSSLTransportParameters
- * [THRIFT-4566] - Pass message of unhandled exception to optional rethrow.
- * [THRIFT-4506] - Remove assertion in Java SASL code that would be ignored in release builds
- * [THRIFT-4470] - Include popular IDE file templates to gitignore
- * [THRIFT-4429] - Make TThreadPoolServer.executorService_ available in inherited classes and refactor methods to be able customization
- * [THRIFT-3769] - Fix logic of THRIFT-2268
- * [THRIFT-4494] - Increase Java Socket Buffer Size
- * [THRIFT-4499] - Remove Magic Number In TFIleTransport
-
-## js
- * [THRIFT-4406] - JavaScript: Use modern Promise implementations
- * [THRIFT-4625] - let / const variable decorators for es6 compiler
- * [THRIFT-4653] - ES6 Classes
- * [THRIFT-4592] - JS: readI32 performance on large arrays is very poor in Chrome
- * [THRIFT-4509] - js and nodejs libraries need to be refreshed with current libraries
- * [THRIFT-4403] - thrift.js: Incorrect usage of 'this' in TWebSocketTransport.__onOpen
- * [THRIFT-4436] - Deserialization of nested list discards content
- * [THRIFT-4437] - JS WebSocket client callbacks invoked twice on parallel requests
- * [THRIFT-4679] - Duplicate declaration of InputBufferUnderrunError in lib/nodejs/lib/thrift/json_protocol.js
- * [THRIFT-4551] - Add prettier for consistent JS code formatting
-
-## lua
- * [THRIFT-4591] - lua client uses two write() calls per framed message send
- * [THRIFT-3863] - Can't "make install" Lua Library
-
-## netcore
- * [THRIFT-4524] - .NET Core Server doesn't close properly when cancelled
- * [THRIFT-4434] - Update .NET Core components, add tests for .Net Core library and .Net Core compiler, fix bugs and build process
- * [THRIFT-4446] - JSONProtocol Base64 Encoding Trims Padding
-
-## node.js
- * [THRIFT-4225] - Error handling malformed arguments leaks memory, corrupts transport buffers causing next RPC to fail
- * [THRIFT-3950] - Memory leak while calling oneway method
- * [THRIFT-3143] - add typescript directory support
- * [THRIFT-4564] - TBufferedTransport can leave corrupt data in the buffer
- * [THRIFT-4647] - Node.js Fileserver webroot path
- * [THRIFT-4489] - Unix domain socket support for NodeJS client
- * [THRIFT-4443] - node.js json_protocol throws error in skip function
- * [THRIFT-4604] - NodeJS: Expose Int64 from browser.js for consumption by browser
- * [THRIFT-4480] - NodeJS warning on binary_protocol writeMessageEnd when seqid = 0
-
-## perl
- * [THRIFT-4382] - Replace the use of Perl Indirect Object Syntax calls to new()
- * [THRIFT-4471] - Thrift CPAN release is missing Makefile.PL and the clients are unable to build the module
- * [THRIFT-4416] - Perl CPAN Packaging Improvements
-
-## php
- * [THRIFT-4474] - PHP generator use PSR-4 default
- * [THRIFT-4463] - PHP generated code match PSR-2
- * [THRIFT-4373] - Extending Thrift class results in "Attempt serialize from non-Thrift object"
- * [THRIFT-4354] - TSocket block on read
- * [THRIFT-4423] - migrate php library to psr-4
- * [THRIFT-4656] - infinite loop in latest PHP library
- * [THRIFT-4477] - TBufferedTransport must have underlying transport
- * [THRIFT-4475] - lib/php/test should be checked for PSR-2
- * [THRIFT-4498] - add phpcs back
- * [THRIFT-4460] - php library use PSR-2
- * [THRIFT-4641] - TCurlClient doesn't check for HTTP status code
- * [THRIFT-4645] - TCurlClient: show actual error message when throwing TTransportException
- * [THRIFT-4674] - Add stream context support into PHP/THttpClient
- * [THRIFT-4459] - reduce php library directory depth
-
-## python
- * [THRIFT-4670] - Twisted, slots, and void method fails with "object has no attribute 'success'"
- * [THRIFT-4464] - Potentially server-crashing typo in Python TNonblockingServer
- * [THRIFT-4548] - Supporting TBinaryProtocolAccelerated protocol when using TMultiplexedProcessor in Python
- * [THRIFT-4577] - Outdated cipher string in python unit test
- * [THRIFT-4505] - python build on Vagrant Windows boxes fails
- * [THRIFT-4621] - THeader for Python
- * [THRIFT-4668] - make socket backlog configurable for python
- * [THRIFT-4561] - Python: cleanup socket timeout settings
-
-## ruby
- * [THRIFT-4289] - Thrift RSpec test suite fails with Ruby 2.4.x due to Fixnum deprecation
- * [THRIFT-4342] - Support ruby rspec 3
- * [THRIFT-4525] - Add ssl socket option to ruby cross tests
- * [THRIFT-4450] - Add seek support to TCompactInputProtocol in Rust
- * [THRIFT-4631] - Codegen Creates Invalid Ruby for Recursive Structs
- * [THRIFT-4472] - Fix the genspec for ruby so it does not complain about an invalid license
-
-## rust
- * [THRIFT-4662] - Rust const string calls function at compile time
- * [THRIFT-4661] - Rust enum name wrong case in generated structs
- * [THRIFT-4617] - Avoid generating conflicting struct names in Rust code
- * [THRIFT-4529] - Rust generation should include #![allow(non_snake_case)] or force conform to Rust style guidelines
- * [THRIFT-4390] - Rust binary protocol and buffered transport cannot handle writes above 4096 bytes
- * [THRIFT-4419] - Rust framed transport cannot handle writes above 4096 bytes
- * [THRIFT-4658] - Rust's TBinaryInputProtocol fails when strict is false
- * [THRIFT-4187] - Dart -> Rust Framed cross tests fail
- * [THRIFT-4664] - Rust cannot create ReadHalf/WriteHalf to implement custom tranports
-
-## swift (new language support in 0.12.0)
- * [THRIFT-3773] - Swift Library
-
-## test suite
- * [THRIFT-4515] - Gracefully shutdown cross-test servers to fully test teardown
- * [THRIFT-4085] - Add .NET Core to the make cross standard test suite
- * [THRIFT-4358] - Add unix domain sockets in ruby to cross test - code exists
-
-## typescript (new language support in 0.12.0)
- * [THRIFT-3143] - add typescript directory support
-
-================================================================================
-Thrift 0.11.0
---------------------------------------------------------------------------------
-## Sub-task
- * [THRIFT-2733] - Erlang coding standards
- * [THRIFT-2740] - Perl coding standards
- * [THRIFT-3610] - Streamline exception handling in Python server handler
- * [THRIFT-3686] - Java processor should report internal error on uncaught exception
- * [THRIFT-4049] - Skip() should throw TProtocolException.INVALID_DATA on unknown data types
- * [THRIFT-4053] - Skip() should throw TProtocolException.INVALID_DATA on unknown data types
- * [THRIFT-4136] - Align is_binary() method with is_string() to simplify those checks
- * [THRIFT-4137] - Fix remaining undefined behavior invalid vptr casts in Thrift Compiler
- * [THRIFT-4138] - Fix remaining undefined behavior invalid vptr casts in C++ library
- * [THRIFT-4296] - Fix Ubuntu Xenial build environment for the python language
- * [THRIFT-4298] - Fix Ubuntu Xenial build environment for the go 1.6 language
- * [THRIFT-4299] - Fix Ubuntu Xenial build environment for the D language
- * [THRIFT-4300] - Fix make cross in Ubuntu Xenial docker environment, once all language support issues are fixed
- * [THRIFT-4302] - Fix Ubuntu Xenial make cross testing for lua and php7
- * [THRIFT-4398] - Update EXTRA_DIST for "make dist"
-
-## Bug
- * [THRIFT-381] - Fail fast if configure detects C++ problems
- * [THRIFT-1677] - MinGW support broken
- * [THRIFT-1805] - Thrift should not swallow ALL exceptions
- * [THRIFT-2026] - Fix TCompactProtocol 64 bit builds
- * [THRIFT-2642] - Recursive structs don't work in python
- * [THRIFT-2889] - stable release 0.9.2, erlang tutorial broken
- * [THRIFT-2913] - Ruby Server Thrift::ThreadPoolServer should serve inside a thread
- * [THRIFT-2998] - Node.js: Missing header from http request
- * [THRIFT-3000] - .NET implementation has trouble with mixed IP modes
- * [THRIFT-3281] - Travis CI build passed but the log says BUILD FAILED
- * [THRIFT-3358] - Makefile:1362: *** missing separator. Stop.
- * [THRIFT-3600] - Make TTwisted server send exception on unexpected handler error
- * [THRIFT-3602] - Make Tornado server send exception on unexpected handler error
- * [THRIFT-3657] - D TFileWriterTransport close should use non-priority send
- * [THRIFT-3700] - Go Map has wrong default value when optional
- * [THRIFT-3703] - Unions Field Count Does Not Consider Map/Set/List Fields
- * [THRIFT-3730] - server log error twice
- * [THRIFT-3778] - go client can not pass method parameter to server of other language if no field_id is given
- * [THRIFT-3784] - thrift-maven-plugin generates invalid include directories for IDL in dependency JARs
- * [THRIFT-3801] - Node Thrift client throws exception with multiplexer and responses that are bigger than a single buffer
- * [THRIFT-3821] - TMemoryBuffer buffer may overflow when resizing
- * [THRIFT-3832] - Thrift version 0.9.3 example on Windows, Visual Studio, linking errors during compiling
- * [THRIFT-3847] - thrift/config.h includes a #define for VERSION which will likely conflict with existing user environment or code
- * [THRIFT-3873] - Fix various build warnings when using Visual Studio
- * [THRIFT-3891] - TNonblockingServer configured with more than one IO threads does not always return from serve() upon stop()
- * [THRIFT-3892] - Thrift uses TLS SNI extension provided by OpenSSL library. Older version of OpenSSL(< 0.9.8f) may create problem because they do not support 'SSL_set_tlsext_host_name()'.
- * [THRIFT-3895] - Build fails using Java 1.8 with Ant < 1.9
- * [THRIFT-3896] - map<string,string> data with number string key cannot access that deserialized by php extension
- * [THRIFT-3938] - Python TNonblockingServer does not work with SSL
- * [THRIFT-3944] - TSSLSocket has dead code in checkHandshake
- * [THRIFT-3946] - Java 1.5 compatibility broken for binary fields (java5 option)
- * [THRIFT-3960] - Inherited services in Lua generator are not named correctly
- * [THRIFT-3962] - Ant build.xml broken on Windows for Java library
- * [THRIFT-3963] - Thrift.cabal filename does not match module name
- * [THRIFT-3967] - gobject/gparam.h:166:33: warning: enumerator value for ‘G_PARAM_DEPRECATED’ is not an integer constant expression
- * [THRIFT-3968] - Deserializing empty string/binary fields
- * [THRIFT-3974] - Using clang-3.8 and ThreadSanitizer on the concurrency_test claims bad PThread behavior
- * [THRIFT-3984] - PHP7 extension causes segfault
- * [THRIFT-4008] - broken ci due to upstream dependency versioning break
- * [THRIFT-4009] - Use @implementer instead of implements in TTwisted.py
- * [THRIFT-4010] - Q.fcall messing up with *this* pointer inside called function
- * [THRIFT-4011] - Sets of Thrift structs generate Go code that can't be serialized to JSON
- * [THRIFT-4012] - Python Twisted implementation uses implements, not compatible with Py3
- * [THRIFT-4014] - align C# meta data in AssemblyInfo.cs
- * [THRIFT-4015] - Fix wrongly spelled "Thirft"s
- * [THRIFT-4016] - testInsanity() impl does not conform to test spec in ThriftTest.thrift
- * [THRIFT-4023] - Skip unexpected field types on read/write
- * [THRIFT-4024] - Skip() should throw on unknown data types
- * [THRIFT-4026] - TSSLSocket doesn't work with Python < 2.7.9
- * [THRIFT-4029] - Accelerated protocols do not build from thrift-py 0.10.0 on PyPI
- * [THRIFT-4031] - Go plugin generates invalid code for lists of typedef'ed built-in types
- * [THRIFT-4033] - Default build WITH_PLUGIN=ON for all builds results in packaging errors
- * [THRIFT-4034] - CMake doesn't work to build compiler on MacOS
- * [THRIFT-4036] - Add .NET Core environment/build support to the docker image
- * [THRIFT-4038] - socket check: checking an unsigned number against >= 0 never fails
- * [THRIFT-4042] - ExtractionError when using accelerated thrift in a multiprocess test
- * [THRIFT-4043] - thrift perl debian package is placing files in the wrong place
- * [THRIFT-4044] - Build job 17 failing on every pull request; hspec core (haskell) 2.4 issue
- * [THRIFT-4046] - MinGW with gcc 6.2 does not compile on Windows
- * [THRIFT-4060] - Thrift printTo ostream overload mechanism breaks down when types are nested
- * [THRIFT-4062] - Remove debug print from TServiceClient
- * [THRIFT-4065] - Document Perl ForkingServer signal restriction imposed by THRIFT-3848 and remove unnecessary code
- * [THRIFT-4068] - A code comment in Java ServerSocket is wrong around accept()
- * [THRIFT-4073] - enum files are still being generated with unused imports
- * [THRIFT-4076] - Appveyor builds failing because ant 1.9.8 was removed from apache servers
- * [THRIFT-4077] - AI_ADDRCONFIG redefined after recent change to PlatformSocket header
- * [THRIFT-4079] - Generated perl code that returns structures from included thrift files is missing a necessary use clause
- * [THRIFT-4087] - Spurious exception destroying TThreadedServer because of incorrect join() call
- * [THRIFT-4102] - TBufferedTransport performance issue since 0.10.0
- * [THRIFT-4106] - concurrency_test fails randomly
- * [THRIFT-4108] - c_glib thrift ssl has multiple bugs and deprecated functions
- * [THRIFT-4109] - Configure Script uses string comparison for versions
- * [THRIFT-4129] - C++ TNonblockingServer fd leak when failing to dispatch new connections
- * [THRIFT-4131] - Javascript with WebSocket handles oneway methods wrong
- * [THRIFT-4134] - Fix remaining undefined behavior invalid vptr casts
- * [THRIFT-4140] - Use of non-thread-safe function gmtime()
- * [THRIFT-4141] - Installation of haxe in docker files refers to a redirect link and fails
- * [THRIFT-4147] - Rust: protocol should accept transports with non-static lifetime
- * [THRIFT-4148] - [maven-thrift-plugin] compile error while import a thrift in dependency jar file.
- * [THRIFT-4149] - System.out pollutes log files
- * [THRIFT-4154] - PHP close() of a TSocket needs to close any type of socket
- * [THRIFT-4158] - minor issue in README-MSYS2.md
- * [THRIFT-4159] - Building tests fails on MSYS2 (MinGW64) due to a (small?) linker error
- * [THRIFT-4160] - TNonblocking server fix use of closed/freed connections
- * [THRIFT-4161] - TNonBlocking server using uninitialized event in error paths
- * [THRIFT-4162] - TNonBlocking handling of TSockets in error state is incorrect after fd is closed
- * [THRIFT-4164] - Core in TSSLSocket cleanupOpenSSL when destroying a mutex used by openssl
- * [THRIFT-4165] - C++ build has many warnings under c++03 due to recent changes, cmake needs better platform-independent language level control
- * [THRIFT-4166] - Recent fix to remove boost::lexical_cast usage broke VS2010
- * [THRIFT-4167] - Missing compile flag
- * [THRIFT-4170] - Support lua 5.1 or earlier properly for object length determination
- * [THRIFT-4172] - node.js tutorial client does not import assert, connection issues are not handled properly
- * [THRIFT-4177] - Java compiler produces deep copy constructor that could make shallow copy instead
- * [THRIFT-4184] - Building on Appveyor: invalid escape sequence \L
- * [THRIFT-4185] - fb303 counter encoding fix
- * [THRIFT-4189] - Framed/buffered transport Dispose() does not dispose the nested transport
- * [THRIFT-4193] - Lower the default maxReadBufferBytes for non-blocking servers
- * [THRIFT-4195] - Compilation to GO produces broken code
- * [THRIFT-4196] - Cannot generate recursive Rust types
- * [THRIFT-4204] - typo in compact spec
- * [THRIFT-4206] - Strings in container fields are not decoded properly with py:dynamic and py:utf8strings
- * [THRIFT-4208] - C# NamedPipesServer not really working in some scenarios
- * [THRIFT-4211] - Fix GError glib management under Thrift
- * [THRIFT-4212] - c_glib flush tries to close SSL even if socket is invalid
- * [THRIFT-4213] - Travis build fails at curl -sSL https://www.npmjs.com/install.sh | sh
- * [THRIFT-4215] - Golang TTransportFactory Pattern Squelches Errors
- * [THRIFT-4216] - Golang Http Clients Do Not Respect User Options
- * [THRIFT-4218] - Set TCP_NODELAY for PHP client socket
- * [THRIFT-4219] - Golang HTTP clients created with Nil buffer
- * [THRIFT-4231] - TJSONProtocol throws unexpected non-Thrift-exception on null strings
- * [THRIFT-4232] - ./configure does bad ant version check
- * [THRIFT-4234] - Travis build fails cross language tests with "Unsupported security protocol type"
- * [THRIFT-4237] - Go TServerSocket Race Conditions
- * [THRIFT-4240] - Go TSimpleServer does not close properly
- * [THRIFT-4243] - Go TSimpleServer race on wait in Stop() method
- * [THRIFT-4245] - Golang TFramedTransport's writeBuffer increases if writes to transport failed
- * [THRIFT-4246] - Sequence number mismatch on multiplexed clients
- * [THRIFT-4247] - Compile fails with openssl 1.1
- * [THRIFT-4248] - Compile fails - strncpy, memcmp, memset not declared in src/thrift/transport/TSSLSocket.cpp
- * [THRIFT-4251] - Java Epoll Selector Bug
- * [THRIFT-4257] - Typescript async callbacks do not provide the correct types
- * [THRIFT-4258] - Boost/std thread wrapping faultiness
- * [THRIFT-4260] - Go context generation issue. Context is parameter in Interface not in implementation
- * [THRIFT-4261] - Go context generation issue: breaking change in generated code regarding thrift.TProcessorFunction interface
- * [THRIFT-4262] - Invalid binding to InterlockedCompareExchange64() with 64-bit targets
- * [THRIFT-4263] - Fix use after free bug for thrown exceptions
- * [THRIFT-4266] - Erlang library throws during skipping fields of composite type (maps, lists, structs, sets)
- * [THRIFT-4268] - Erlang library emits debugging output in transport layer
- * [THRIFT-4273] - erlang:now/0: Deprecated BIF.
- * [THRIFT-4274] - Python feature tests for SSL/TLS failing
- * [THRIFT-4279] - Wrong path in include directive in generated Thrift sources
- * [THRIFT-4283] - TNamedPipeServer race condition in interrupt
- * [THRIFT-4284] - File contains a NBSP: lib/nodejs/lib/thrift/web_server.js
- * [THRIFT-4290] - C# nullable option generates invalid code for non-required enum field with default value
- * [THRIFT-4292] - TimerManager::remove() is not implemented
- * [THRIFT-4307] - Make ssl-open timeout effective in golang client
- * [THRIFT-4312] - Erlang client cannot connect to Python server: exception error: econnrefused
- * [THRIFT-4313] - Program code of the Erlang tutorial files contain syntax errors
- * [THRIFT-4316] - TByteBuffer.java will read too much data if a previous read returns fewer bytes than requested
- * [THRIFT-4319] - command line switch for "evhttp" incorrectly resolved to anon pipes
- * [THRIFT-4323] - range check errors or NPE in edge cases
- * [THRIFT-4324] - field names can conflict with local vars in generated code
- * [THRIFT-4328] - Travis CI builds are timing out (job 1) and haxe builds are failing since 9/11
- * [THRIFT-4329] - c_glib Doesn't have a multiplexed processor
- * [THRIFT-4331] - C++: TSSLSockets bug in handling huge messages, bug in handling polling
- * [THRIFT-4332] - Binary protocol has memory leaks
- * [THRIFT-4334] - Perl indentation incorrect when defaulting field attribute to a struct
- * [THRIFT-4339] - Thrift Framed Transport in Erlang crashes server when client disconnects
- * [THRIFT-4340] - Erlang fix a crash on client close
- * [THRIFT-4355] - Javascript indentation incorrect when defaulting field attribute to a struct
- * [THRIFT-4356] - thrift_protocol call Transport cause Segmentation fault
- * [THRIFT-4359] - Haxe compiler looks like it is producing incorrect code for map or set key that is binary type
- * [THRIFT-4362] - Missing size-check can lead to huge memory allocation
- * [THRIFT-4364] - Website contributing guide erroneously recommends submitting patches in JIRA
- * [THRIFT-4365] - Perl generated code uses indirect object syntax, which occasionally causes compilation errors.
- * [THRIFT-4367] - python TProcessor.process is missing "self"
- * [THRIFT-4370] - Ubuntu Artful cppcheck and flake8 are more stringent and causing SCA build job failures
- * [THRIFT-4372] - Pipe write operations across a network are limited to 65,535 bytes per write.
- * [THRIFT-4374] - cannot load thrift_protocol due to undefined symbol: _ZTVN10__cxxabiv120__si_class_type_infoE
- * [THRIFT-4376] - Coverity high impact issue resolution
- * [THRIFT-4377] - haxe. socket handles leak in TSimpleServer
- * [THRIFT-4381] - Wrong isset bitfield value after transmission
- * [THRIFT-4385] - Go remote client -u flag is broken
- * [THRIFT-4392] - compiler/..../plugin.thrift structs mis-ordered blows up ocaml generator
- * [THRIFT-4395] - Unable to build in the ubuntu-xenial docker image: clap 2.28 requires Rust 1.20
- * [THRIFT-4396] - inconsistent (or plain wrong) version numbers in master/trunk
-
-## Documentation
- * [THRIFT-4157] - outdated readme about Haxe installation on Linux
-
-## Improvement
- * [THRIFT-105] - make a thrift_spec for a structures with negative tags
- * [THRIFT-281] - Cocoa library code needs comments, badly
- * [THRIFT-775] - performance improvements for Perl
- * [THRIFT-2221] - Generate c++ code with std::shared_ptr instead of boost::shared_ptr.
- * [THRIFT-2364] - OCaml: Use Oasis exclusively for build process
- * [THRIFT-2504] - TMultiplexedProcessor should allow registering default processor called if no service name is present
- * [THRIFT-3207] - Enable build with OpenSSL 1.1.0 series
- * [THRIFT-3272] - Perl SSL Authentication Support
- * [THRIFT-3357] - Generate EnumSet/EnumMap where elements/keys are enums
- * [THRIFT-3369] - Implement SSL/TLS support on C with c_glib
- * [THRIFT-3467] - Go Maps for Thrift Sets Should Have Values of Type struct{}
- * [THRIFT-3580] - THeader for Haskell
- * [THRIFT-3627] - Missing basic code style consistency of JavaScript.
- * [THRIFT-3706] - There's no support for Multiplexed protocol on c_glib library
- * [THRIFT-3766] - Add getUnderlyingTransport() to TZlibTransport
- * [THRIFT-3776] - Go code from multiple thrift files with the same namespace
- * [THRIFT-3823] - Escape documentation while generating non escaped documetation
- * [THRIFT-3854] - allow users to clear read buffers
- * [THRIFT-3859] - Unix Domain Socket Support in Objective-C
- * [THRIFT-3921] - C++ code should print enums as strings
- * [THRIFT-3926] - There should be an error emitted when http status code is not 200
- * [THRIFT-4007] - Micro-optimization of TTransport.py
- * [THRIFT-4040] - Add real cause of TNonblockingServerSocket error to exception
- * [THRIFT-4064] - Update node library dependencies
- * [THRIFT-4069] - All perl packages should have proper namespace, version syntax, and use proper thrift exceptions
- * [THRIFT-4071] - Consolidate the Travis CI jobs where possible to put less stress on the Apache Foundation's allocation of CI build slaves
- * [THRIFT-4072] - Add the possibility to send custom headers in TCurlClient
- * [THRIFT-4075] - Better MinGW support for headers-only boost (without thread library)
- * [THRIFT-4081] - Provide a MinGW 64-bit Appveyor CI build for better pull request validation
- * [THRIFT-4084] - Improve SSL security in thrift by adding a make cross client that checks to make sure SSLv3 protocol cannot be negotiated
- * [THRIFT-4095] - Add multiplexed protocol to Travis CI for make cross
- * [THRIFT-4099] - Auto-derive Hash for generated Rust structs
- * [THRIFT-4110] - The debian build files do not produce a "-dbg" package for debug symbols of libthrift0
- * [THRIFT-4114] - Space after '///' in doc comments
- * [THRIFT-4126] - Validate objects in php extension
- * [THRIFT-4130] - Ensure Apache Http connection is released back to pool after use
- * [THRIFT-4151] - Thrift Mutex Contention Profiling (pthreads) should be disabled by default
- * [THRIFT-4176] - Implement a threaded and threadpool server type for Rust
- * [THRIFT-4183] - Named pipe client blocks forever on Open() when there is no server at the other end
- * [THRIFT-4190] - improve C# TThreadPoolServer defaults
- * [THRIFT-4197] - Implement transparent gzip compression for HTTP transport
- * [THRIFT-4198] - Ruby should log Thrift internal errors to global logger
- * [THRIFT-4203] - thrift server stop gracefully
- * [THRIFT-4205] - c_glib is not linking against glib + gobject
- * [THRIFT-4209] - warning CS0414 in T[TLS]ServerSocket.cs
- * [THRIFT-4210] - include Thrift.45.csproj into CI runs
- * [THRIFT-4217] - HttpClient should support gzip and deflate
- * [THRIFT-4222] - Support Unix Domain Sockets in Golang TServerSocket
- * [THRIFT-4233] - Make THsHaServer.invoker available (get method only) in inherited classes
- * [THRIFT-4236] - Support context in go generated code.
- * [THRIFT-4238] - JSON generator: make annotation-aware
- * [THRIFT-4269] - Don't append '.' to Erlang namespace if it ends in '_'.
- * [THRIFT-4270] - Generate Erlang mapping functions for const maps and lists
- * [THRIFT-4275] - Add support for zope.interface only, apart from twisted support.
- * [THRIFT-4285] - Pull generated send/recv into library to allow behaviour to be customised
- * [THRIFT-4287] - Add c++ compiler "no_skeleton" flag option
- * [THRIFT-4288] - Implement logging levels properly for node.js
- * [THRIFT-4295] - Refresh the Docker image file suite for Ubuntu, Debian, and CentOS
- * [THRIFT-4305] - Emit ddoc for generated items
- * [THRIFT-4306] - Thrift imports not replicated to D service output
- * [THRIFT-4315] - Add default message for TApplicationException
- * [THRIFT-4318] - Delphi performance improvements
- * [THRIFT-4325] - Simplify automake cross compilation by relying on one global THRIFT compiler path
- * [THRIFT-4327] - Improve TimerManager API to allow removing specific task
- * [THRIFT-4330] - Allow unused crates in Rust files
- * [THRIFT-4333] - Erlang tutorial examples are using a different port (9999)
- * [THRIFT-4343] - Change CI builds to use node.js 8.x LTS once available
- * [THRIFT-4345] - Create a docker build environment that uses the minimum supported language levels
- * [THRIFT-4346] - Allow Zlib transport factory to wrap other transports
- * [THRIFT-4348] - Perl HTTP Client custom HTTP headers
- * [THRIFT-4350] - Update netcore build for dotnet 2.0 sdk and make cross validation
- * [THRIFT-4351] - Use Travis CI Build Stages to optimize the CI build
- * [THRIFT-4353] - cannot read via thrift_protocol at server side
- * [THRIFT-4378] - add set stopTimeoutUnit method to TThreadPoolServer
-
-## New Feature
- * [THRIFT-750] - C++ Compiler Virtual Function Option
- * [THRIFT-2945] - Implement support for Rust language
- * [THRIFT-3857] - thrift js:node complier support an object as parameter not an instance of struct
- * [THRIFT-3933] - Port official C# .NET library for Thrift to C# .NET Core libary
- * [THRIFT-4039] - Update of Apache Thrift .Net Core lib
- * [THRIFT-4113] - Provide a buffer transport for reading/writing in memory byte stream
-
-## Question
- * [THRIFT-2956] - autoconf - possibly undefined macro - AC_PROG_BISON
- * [THRIFT-4223] - Add support to the isServing() method for the C++ library
-
-## Task
- * [THRIFT-3622] - Fix deprecated uses of std::auto_ptr
- * [THRIFT-4028] - Please remove System.out.format from the source code
- * [THRIFT-4186] - Build and test rust client in Travis
-
-## Test
- * [THRIFT-4264] - PHP - Support both shared & static linking of sockets library
-
-## Wish
- * [THRIFT-4344] - Define and maintain the minimum language level for all languages in one place
-
-
-Thrift 0.10.0
---------------------------------------------------------------------------------
-## Bug
- * [THRIFT-1840] - Thrift Generated Code Causes Global Variable Leaks
- * [THRIFT-1828] - moc_TQTcpServer.cpp was removed from source tree but is in thrift-0.9.0.tar.gz
- * [THRIFT-1790] - cocoa: Duplicate interface definition error
- * [THRIFT-1776] - TPipeServer should implement "listen", so that TServerEventHandler preServe will work right
- * [THRIFT-1351] - Compiler does not care about binary strings
- * [THRIFT-1229] - Python fastbinary.c can not handle unicode as generated python code
- * [THRIFT-749] - C++ TBufferedTransports do not flush their buffers on delete
- * [THRIFT-747] - C++ TSocket->close calls shutdown breaking forked parent process
- * [THRIFT-732] - server exits abnormally when client calls send_xxx function without calling recv_xxx function
- * [THRIFT-3942] - TSSLSocket does not honor send and receive timeouts
- * [THRIFT-3941] - WinXP version of thrift_poll() relies on undefined behavior by passing a destructed variable to select()
- * [THRIFT-3940] - Visual Studio project file for compiler is broken
- * [THRIFT-3943] - Coverity Scan identified some high severity defects
- * [THRIFT-3929] - PHP "nsglobal" Option Results in Syntax Error in Generated Code (Trailing Backslash)
- * [THRIFT-3936] - Cannot compile 0.10.0 development tip with VS2013 and earlier (snprintf, uint32_t)
- * [THRIFT-3935] - Incorrect skipping of map and set
- * [THRIFT-3920] - Ruby: Ensuring that HTTP failures will clear the http transport outbuf var
- * [THRIFT-3919] - C# TTLSServerSocket does not use clientTimeout
- * [THRIFT-3917] - Check backports.ssl_match_hostname module version
- * [THRIFT-3909] - Fix c_glib static lib CMake build
- * [THRIFT-3904] - Typo in node tutorial leads to wrong transport being used
- * [THRIFT-3848] - As an implementer of a perl socket server, I do not want to have to remember to ignore SIGCHLD for it to work properly
- * [THRIFT-3844] - thrift_protocol cannot compile in 7.0.7
- * [THRIFT-3843] - integer issues with Haxe PHP targets cause ZigZag encoding to fail
- * [THRIFT-3842] - Dart generates incorrect code for a const struct
- * [THRIFT-3841] - dart compact protocol incorrectly serializes/deserialized doubles
- * [THRIFT-3708] - NameError: global name 'TProtocol' is not defined
- * [THRIFT-3704] - "TConnectedClient died: Could not refill buffer" message shown when using HTTP Server
- * [THRIFT-3678] - Fix javadoc errors on JDK 8
- * [THRIFT-3014] - AppVeyor support
- * [THRIFT-2994] - Node.js TJSONProtocol cannot be used for object serialization.
- * [THRIFT-2974] - writeToParcel throws NPE for optional enum fields
- * [THRIFT-2948] - Python TJSONProtocol doesn't handle structs with binary fields containing invalid unicode.
- * [THRIFT-2845] - ChildService.Plo: No such file or directory
- * [THRIFT-3276] - Binary data does not decode correctly using the TJSONProtocol when the base64 encoded data is padded.
- * [THRIFT-3253] - Using latest version of D gives deprecation notices
- * [THRIFT-2883] - TTwisted.py, during ConnectionLost processing: exceptions.RuntimeError: dictionary changed size during iteration
- * [THRIFT-2019] - Writing on a disconnected socket on Mac causes SIG PIPE
- * [THRIFT-2020] - Thrift library has some empty files that haven't really been deleted
- * [THRIFT-2049] - Go compiler doesn't build on native Windows
- * [THRIFT-2024] - TServer.cpp warns on 64-bit platforms about truncating an rlim_t into an int
- * [THRIFT-2023] - gettimeofday implementation on Windows errors when no time zone is passed in.
- * [THRIFT-2022] - CoB and dense code generation still uses TR1 bind, even though that doesn't work with clang
- * [THRIFT-2027] - Minor 64-bit and NOMINMAX issues in C++ library
- * [THRIFT-2156] - TServerSocket::listen() is throwing exceptions with misleading information
- * [THRIFT-2154] - Missing <operator body
- * [THRIFT-2148] - TNonblockingMultiFetchClient imports log4j
- * [THRIFT-2103] - [python] Support for SSL certificates with Subject Alternative Names
- * [THRIFT-1931] - Sending a frame size of zero to a TNonblockingServer causes an assertion failure
- * [THRIFT-1751] - definition of increase_max_fds doesn't compile when HAVE_SYS_RESOURCE_H is not defined
- * [THRIFT-1522] - TServerSocket potential memory leak with addrinfo *res0
- * [THRIFT-1547] - Problems building against static libevent
- * [THRIFT-1545] - Generated javascript code uses "for in" for looping over arrays
- * [THRIFT-1487] - Namespace problem, compile fails on generated code
- * [THRIFT-1472] - Configuration conflicts with boost platform include header
- * [THRIFT-6] - Thrift libraries and compiler lack version number
- * [THRIFT-1680] - make install requires GNU make
- * [THRIFT-3869] - Dart Tutorial build fails with Error 65 at "pub get"
- * [THRIFT-3861] - Travis CI builds are timing out - C++TServerIntegrationTest appears to be hanging
- * [THRIFT-3855] - In the go simple server, if Stop() is called multiple times it hangs
- * [THRIFT-3885] - PHP: Error when readI64 in TCompactProtocol
- * [THRIFT-3883] - Go TestAllConnection can fail with port 9090 collision
- * [THRIFT-3884] - Fix Erlang compact protocol double endianess and boolean list
- * [THRIFT-3880] - Erlang Compact protocol - boolean values inverted
- * [THRIFT-3879] - Undefined evaluation order causes incorrect processing in the C++ library JSON protocol
- * [THRIFT-3851] - Golang thrift continually adds the x/thrift content type
- * [THRIFT-3850] - All apache builds are failing when initiated from a github pull request
- * [THRIFT-3837] - Thift 0.9.3 can't be build with QuickCheck 2.8.2 and unordered-containers 0.2.6
- * [THRIFT-3831] - build of test/cpp/src/TestClient.cpp fails with newer gcc on platforms with unsigned char due to narrowing conversions
- * [THRIFT-3827] - php CompactProtocol readI64 function has bug, when value has 32bit ~64bit, Example:value=1461563457000
- * [THRIFT-3825] - Javascript test dependency is no longer available
- * [THRIFT-3814] - Fix contention in TNonblockingServerTest
- * [THRIFT-3793] - Appveyor builds reference an ant version that is no longer there
- * [THRIFT-3786] - Node.js TLS emits 'connect' before connection is ready
- * [THRIFT-3780] - Fix dart int64 usage when compiled to js
- * [THRIFT-3789] - Node.js lacks ability to destroy connection
- * [THRIFT-3796] - There's no --dbg for dh_strip, maybe someone has mistaken this for --dbg-package.
- * [THRIFT-3795] - Generated hashValue method in Swift will overflow
- * [THRIFT-3790] - Fix Delphi named pipe client to use timeout even when pipe doesn't yet exist
- * [THRIFT-3787] - Node.js Connection object doesn't handle errors correctly
- * [THRIFT-3791] - Delphi pipe client may fail even in a non-error condition
- * [THRIFT-3771] - TBufferedTransport gets in invalid state on read/write errors
- * [THRIFT-3764] - PHP "make install" does not install TMultiplexedProtocol.php nor TSimpleJSONProtocol.php
- * [THRIFT-3768] - TThreadedServer may crash if it is destroyed immediately after it returns from serve(); TThreadedServer disconnects clients
- * [THRIFT-3765] - memory leak in python compact protocol extension
- * [THRIFT-3758] - TApplicationException::getType and TProtocolException::getType should be const
- * [THRIFT-3763] - Fix serialization of i64 larger than 2^53 for browserify
- * [THRIFT-3759] - required fields that are nil are silently ignored on write
- * [THRIFT-3753] - TServerFramework::stop may fail to interrupt connected clients
- * [THRIFT-3755] - TDebugProtocol::writeString hits assert in isprint on Windows with debug CRT
- * [THRIFT-3751] - Compiler allows field ids that are too large for generated code
- * [THRIFT-3748] - Node.js Deserialization of lists of lists is broken
- * [THRIFT-3760] - Fix install paths etc of debian packages for py and perl
- * [THRIFT-3757] - Fix various build warnings on Windows with VS2015 compiler
- * [THRIFT-3750] - NSCopying copyWithZone: implementation does not check isSet
- * [THRIFT-3747] - Duplicate node.js build on Travis-CI
- * [THRIFT-3744] - The precision should be 17 (16 bits need after dot) after dot for double type.
- * [THRIFT-3741] - haxe test is broken
- * [THRIFT-3739] - Deprecation warning in codegen/base.d
- * [THRIFT-3735] - JSON protocol left in incorrect state when an exception is thrown during read or write operations
- * [THRIFT-3734] - To compare two string as lowercase.
- * [THRIFT-3743] - Java JSON protocol left in incorrect state when an exception is thrown during read or write operations
- * [THRIFT-3731] - Perl multiplex test is flaky
- * [THRIFT-3729] - Restrict rake version
- * [THRIFT-3727] - Incorrect require paths in Node.js tutorial
- * [THRIFT-3723] - Fix Lua include path
- * [THRIFT-3722] - Fix cert path in C++ cross tests for non-Linux platform
- * [THRIFT-3726] - Fix incorrect conditional in TMultiplexedProcessor.py
- * [THRIFT-3725] - Skip a flaky cross test entry (d-dart compact framed-ip)
- * [THRIFT-3724] - Fix incorrect timeval conversion in libevent.d
- * [THRIFT-3721] - CLONE - why not add unicode strings support to python directly?
- * [THRIFT-3720] - TTcpSocketStreamImpl.Read() returns 0 if not all requested bytes could be read
- * [THRIFT-3719] - Dart generator should use lowerCamelCase for service names
- * [THRIFT-3902] - TSocket.open throws NullPointerException
- * [THRIFT-3901] - TFramedTransport.open throws NullPointerException
- * [THRIFT-3893] - Command injection in format_go_output
- * [THRIFT-3807] - Swift compiler does not escape reserved words
- * [THRIFT-3798] - THttpClient does not use proxy from http_proxy, https_proxy environment variables
- * [THRIFT-3809] - wrong/unused BINARY type code
- * [THRIFT-3806] - Swift generator does not handle self-referring structs
- * [THRIFT-3805] - Golang server susceptible to memory spike from malformed message
- * [THRIFT-3797] - Generated Delphi processor shouldn't error out on timed out exceptions
- * [THRIFT-3813] - Appveyor builds reference an openssl version that is no longer there
- * [THRIFT-3658] - Missing file in THRIFT-3599
- * [THRIFT-3649] - Python TSaslClientTransport initializes TTransportException incorrectly
- * [THRIFT-3650] - incorrect union serialization
- * [THRIFT-3713] - lib/d/test/thrift_test_runner.sh is flaky on Jenkins
- * [THRIFT-3668] - range check error in compact protocol
- * [THRIFT-3663] - CMake cpp test fails to build on system without zlib
- * [THRIFT-3712] - TTornadoServer cannot handle IPv6 address
- * [THRIFT-3710] - Dart generator does not camel case Constants class names
- * [THRIFT-3697] - Dart generator does not name imports
- * [THRIFT-3690] - Work around docker image build failures on Travis-CI
- * [THRIFT-3689] - thrift_reconnecting_client start failed when server is not available
- * [THRIFT-3695] - Fix D test scripts
- * [THRIFT-3675] - Union is not serialized correctly by Thrift C Glib
- * [THRIFT-3673] - API fails with std::exception after a timeout occured in earlier any API call
- * [THRIFT-3709] - Comment syntax can produce broken code
- * [THRIFT-3705] - Go map has incorrect types when used with forward-defined types
- * [THRIFT-3702] - Fix cross tests for Dart compact protocol (3 failing)
- * [THRIFT-3683] - BadYieldError in thrift py:tornado server
- * [THRIFT-3682] - Do not reuse refused sockets in test scripts
- * [THRIFT-3681] - Fix Dart tutorial build
- * [THRIFT-3680] - Java async processor fails to notify errors to clients
- * [THRIFT-3714] - Thrift.TProtocolException is not defined in js/src/thrift.js
- * [THRIFT-3688] - Fix socket bind failure detection of cross test
- * [THRIFT-3641] - Ruby client should try to connect to every result of getaddrinfo
- * [THRIFT-3635] - D transport_test is flaky on Jenkins and Travis
- * [THRIFT-3618] - Python TSSLSocket deprecation message should print caller's location
- * [THRIFT-3145] - JSON protocol does not handle bool and empty containers correctly
- * [THRIFT-3158] - TBase<T,F>#deepCopy should return T
- * [THRIFT-3157] - TBase signature should be TBase<T extends TBase<T,F>, F extends TFieldIdEnum>
- * [THRIFT-3156] - Node TLS: server executes processing logic two full times
- * [THRIFT-3154] - tutorial/py.tornado throw EOF exception
- * [THRIFT-3063] - C++ build -Wunused-parameter warnings on processor_test, TransportTest
- * [THRIFT-3056] - Add string/collection length limits for Python protocol readers
- * [THRIFT-3237] - Fix TNamedPipeServer::createNamedPipe memory leak
- * [THRIFT-3233] - Fix C++ ThreadManager::Impl::removeWorker worker join
- * [THRIFT-3232] - Cannot deserialize json messages created with fieldNamesAsString
- * [THRIFT-3206] - Fix Visual Studio build failure due 'pthread_self': identifier not found
- * [THRIFT-3200] - JS and nodejs do not encode JSON protocol binary fields as base64
- * [THRIFT-3199] - Exception field has basic metadata
- * [THRIFT-3182] - TFramedTransport is in an invalid state after frame size exception
- * [THRIFT-2536] - new TSocket, uninitialised value reported by valgrind
- * [THRIFT-2527] - Apache Thrift IDL Compiler code generated for Node.js should be jshint clean
- * [THRIFT-2519] - "processor" class is not being generated
- * [THRIFT-2431] - TFileTransportTest fails with "check delta < XXX failed"
- * [THRIFT-2708] - Erlang library does not support "oneway" message type
- * [THRIFT-3377] - Deep copy is actually shallow when using typedef members
- * [THRIFT-3376] - C# and Python JSON protocol double values lose precision
- * [THRIFT-3373] - Various fixes for cross test servers and clients
- * [THRIFT-3370] - errno extern variable redefined. Not compiling for Android
- * [THRIFT-3379] - Potential out of range panic in Go JSON protocols
- * [THRIFT-3371] - Abstract namespace Unix domain sockets broken in C++
- * [THRIFT-3380] - nodejs: 0.9.2 -> 0.9.3 upgrade breaks Protocol and Transport requires
- * [THRIFT-3367] - Fix bad links to coding_standards.md #634
- * [THRIFT-3401] - Nested collections emit Objective-C code that cannot compile
- * [THRIFT-3403] - JSON String reader doesn't recognize UTF-16 surrogate pairs
- * [THRIFT-3362] - make check fails for C++ at the SecurityTest
- * [THRIFT-3395] - Cocoa compiler produces corrupt code when boxing enums inside map.
- * [THRIFT-3394] - compiler generates uncompilable code
- * [THRIFT-3388] - hash doesn't work on set/list
- * [THRIFT-3391] - Wrong bool formatting in test server
- * [THRIFT-3390] - TTornado server doesn't handle closed connections properly
- * [THRIFT-3382] - TBase class for C++ Library
- * [THRIFT-3392] - Java TZlibTransport does not close its wrapper streams upon close()
- * [THRIFT-3383] - i64 related warnings
- * [THRIFT-3386] - misc. warnings with make check
- * [THRIFT-3385] - warning: format ‘%lu’ expects ‘long unsigned int’, but has type ‘std::basic_string<char>::size_type {aka unsigned int}
- * [THRIFT-3355] - npm WARN package.json thrift@1.0.0-dev No license field.
- * [THRIFT-3360] - Improve cross test servers and clients further
- * [THRIFT-3359] - Binary field incompatibilities
- * [THRIFT-3354] - Fix word-extraction substr bug in initialism code
- * [THRIFT-3350] - Python JSON protocol does not encode binary as Base64
- * [THRIFT-3577] - assertion failed at line 512 of testcontainertest.c
- * [THRIFT-3576] - Boost test --log_format arg does not accept lowercase
- * [THRIFT-3575] - Go compiler tries to use unexported library methods when using read_write_private
- * [THRIFT-3574] - Cocoa generator makes uncompilable imports
- * [THRIFT-3570] - Remove duplicate instances that are added by upstream
- * [THRIFT-3571] - Make feature test result browsable
- * [THRIFT-3569] - c_glib protocols do not check number of bytes read by transport
- * [THRIFT-3568] - THeader server crashes on readSlow
- * [THRIFT-3567] - GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
- * [THRIFT-3566] - C++/Qt: TQTcpServerTest::test_communicate() is never executed
- * [THRIFT-3564] - C++/Qt: potential core dump in TQTcpServer in case an exception occurs in TAsyncProcessor::process()
- * [THRIFT-3558] - typos in c_glib tests
- * [THRIFT-3559] - Fix awkward extra semi-colons with Cocoa container literals
- * [THRIFT-3555] - 'configure' script does not honor --with-openssl=<path> for libcrypto for BN_init
- * [THRIFT-3554] - Constant decls may lead to "Error: internal error: prepare_member_name_mapping() already active for different struct"
- * [THRIFT-3552] - glib_c Memory Leak
- * [THRIFT-3551] - Thrift perl library missing package declaration
- * [THRIFT-3549] - Exceptions are not properly stringified in Perl library
- * [THRIFT-3546] - NodeJS code should not be namespaced (and is currently not strict-mode compliant)
- * [THRIFT-3545] - Container type literals do not compile
- * [THRIFT-3538] - Remove UnboundMethodType in TProtocolDecorator
- * [THRIFT-3536] - Error 'char' does not contain a definition for 'IsLowSurrogate' for WP7 target
- * [THRIFT-3534] - Link error when building with Qt5
- * [THRIFT-3533] - Can not send nil pointer as service method argument
- * [THRIFT-3507] - THttpClient does not use proxy from http_proxy, https_proxy environment variables
- * [THRIFT-3502] - C++ TServerSocket passes small buffer to getsockname
- * [THRIFT-3501] - Forward slash in comment causes compiler error
- * [THRIFT-3498] - C++ library assumes optional function pthread_attr_setschedpolicy is available
- * [THRIFT-3497] - Build fails with "invalid use of incomplete type"
- * [THRIFT-3496] - C++: Cob style client fails when sending a consecutive request
- * [THRIFT-3493] - libthrift does not compile on windows using visual studio
- * [THRIFT-3488] - warning: unused variable 'program'
- * [THRIFT-3489] - warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
- * [THRIFT-3487] - Full support for newer Delphi versions
- * [THRIFT-3528] - Fix warnings in thrift.ll
- * [THRIFT-3527] - -gen py:dynamic,utf8strings ignores utf8strings option
- * [THRIFT-3526] - Code generated by py:utf8strings does not work for Python3
- * [THRIFT-3524] - dcc32 warning "W1000 Symbol 'IsLowSurrogate' is deprecated: 'Use TCharHelper'" in Thrift.Protocol.JSON.pas
- * [THRIFT-3525] - py:dynamic fails to handle binary list/set/map element
- * [THRIFT-3521] - TSimpleJSONProtocolTest is not deterministic (fails when run on JDK 8)
- * [THRIFT-3520] - Dart TSocket onError stream should be typed as Object
- * [THRIFT-3519] - fastbinary does not work with -gen py:utf8strings
- * [THRIFT-3518] - TConcurrentClientSyncInfo files were missing for Visual Studio
- * [THRIFT-3512] - c_glib: Build fails due to missing features.h
- * [THRIFT-3483] - Incorrect empty binary handling introduced by THRIFT-3359
- * [THRIFT-3479] - Oneway calls should not return exceptions to clients
- * [THRIFT-3478] - Restore dropped method to THsHaServer.java
- * [THRIFT-3477] - Parser fails on enum item that starts with 'E' letter and continues with number
- * [THRIFT-3476] - Missing include in ./src/thrift/protocol/TJSONProtocol.cpp
- * [THRIFT-3474] - Docker: thrift-compiler
- * [THRIFT-3473] - When "optional' is used with a struct member, C++ server seems to not return it correctly
- * [THRIFT-3468] - Dart TSocketTransport onError handler is too restrictive
- * [THRIFT-3451] - thrift_protocol PHP extension missing config.m4 file
- * [THRIFT-3456] - rounding issue in static assert
- * [THRIFT-3455] - struct write method's return value is incorrect
- * [THRIFT-3454] - Python Tornado tutorial is broken
- * [THRIFT-3463] - Java can't be disabled in CMake build
- * [THRIFT-3450] - NPE when using SSL
- * [THRIFT-3449] - TBaseAsyncProcessor fb.responseReady() never called for oneway functions
- * [THRIFT-3471] - Dart generator does not handle uppercase argument names
- * [THRIFT-3470] - Sporadic timeouts with pipes
- * [THRIFT-3465] - Go Code With Complex Const Initializer Compilation Depends On Struct Order
- * [THRIFT-3464] - Fix several defects in c_glib code generator
- * [THRIFT-3462] - Cocoa generates Incorrect #import header names
- * [THRIFT-3453] - remove rat_exclude
- * [THRIFT-3418] - Use of ciphers in ssl.wrap_socket() breaks python 2.6 compatibility
- * [THRIFT-3417] - "namespace xsd" is not really working
- * [THRIFT-3413] - Thrift code generation bug in Go when extending service
- * [THRIFT-3420] - C++: TSSLSockets are not interruptable
- * [THRIFT-3415] - include unistd.h conditionally
- * [THRIFT-3414] - #include <pwd.h> in THeaderTransport.h breaks windows build
- * [THRIFT-3411] - Go generates remotes with wrong package qualifiers when including
- * [THRIFT-3430] - Go THttpClient does not read HTTP response body to completion when closing
- * [THRIFT-3423] - First call to thrift_transport:read_exact fails to dispatch correct function
- * [THRIFT-3422] - Go TServerSocket doesn't close on Interrupt
- * [THRIFT-3421] - rebar as dependency instead of bundling (was: rebar fails if PWD contains Unicode)
- * [THRIFT-3428] - Go test fails when running make check
- * [THRIFT-3445] - Throwable messages are hidden from JVM stack trace output
- * [THRIFT-3443] - Thrift include can generate uncompilable code
- * [THRIFT-3444] - Large 64 bit Integer does not preserve value through Node.js JSONProtocol
- * [THRIFT-3436] - misc. cross test issues with UTF-8 path names
- * [THRIFT-3435] - Put generated Java code for fullcamel tests in a separate package/namespace
- * [THRIFT-3433] - Doubles aren't interpreted correctly
- * [THRIFT-3437] - Mingw-w64 build fail
- * [THRIFT-3434] - Dart generator produces empty name in pubspec.yaml for includes without namespaces
- * [THRIFT-3408] - JSON generator emits incorrect types
- * [THRIFT-3406] - Cocoa client should not schedule streams on main runloop
- * [THRIFT-3404] - JSON String reader doesn't recognize UTF-16 surrogate pair
- * [THRIFT-3636] - Double precision is not fully preserved in C++ TJSONProtocol
- * [THRIFT-3632] - c_glib testserialization fails with glib assertion
- * [THRIFT-3619] - Using Thrift 0.9.3 with googletest on Linux gcc 4.9 / C++11
- * [THRIFT-3617] - CMake does not build gv/xml generators
- * [THRIFT-3615] - Fix Python SSL client resource leak on connection failure
- * [THRIFT-3616] - lib/py/test/test_sslsocket.py is flaky
- * [THRIFT-3643] - Perl SSL server crushes if a client disconnect without handshake
- * [THRIFT-3639] - C# Thrift library forces TLS 1.0, thwarting TLS 1.2 usage
- * [THRIFT-3633] - Travis "C C++ - GCC" build was using clang
- * [THRIFT-3634] - Fix Python TSocket resource leak on connection failure
- * [THRIFT-3630] - Debian/Ubuntu install docs need an update
- * [THRIFT-3629] - Parser sets exitcode on errors, but generator does not
- * [THRIFT-3608] - lib/cpp/test/SecurityTest is flaky in jenkins Thrift-precommit build.
- * [THRIFT-3601] - Better conformance to PEP8 for generated code
- * [THRIFT-3599] - Validate client IP address against cert's SubjectAltName
- * [THRIFT-3598] - TBufferedTransport doesn't instantiate client connection
- * [THRIFT-3597] - `make check` hangs in go tests
- * [THRIFT-3589] - Dart generator uses wrong name in constructor for uppercase arguments with defaults
- * [THRIFT-3588] - Using TypeScript with --noImplicitAny fails
- * [THRIFT-3584] - boolean false value cannot be transferred
- * [THRIFT-3578] - Make THeaderTransport detect TCompact framed and unframed
- * [THRIFT-3323] - Python library does not handle escaped forward slash ("/") in JSON
- * [THRIFT-3322] - CMake generated "make check" failes on python_test
- * [THRIFT-3321] - Thrift can't be added as a subdirectory of another CMake-based project
- * [THRIFT-3314] - Dots in file names of includes causes dots in javascript variable names
- * [THRIFT-3307] - Segfault in Ruby serializer
- * [THRIFT-3309] - Missing TConstant.php in /lib/php/Makefile.am
- * [THRIFT-3810] - unresolved external symbol public: virtual void __cdecl apache::thrift::server::TServerFramework::serve(void)
- * [THRIFT-3736] - C++ library build fails if OpenSSL does not surrpot SSLv3
- * [THRIFT-3878] - Compile error in TSSLSocket.cpp with new OpenSSL [CRYPTO_num_locks]
- * [THRIFT-3949] - missing make dist entry for compiler/cpp/test
- * [THRIFT-449] - The wire format of the JSON Protocol may not always be valid JSON if it contains non-UTF8 encoded strings
- * [THRIFT-162] - Thrift structures are unhashable, preventing them from being used as set elements
- * [THRIFT-3961] - TConnectedClient does not terminate the connection to the client if an exception while processing the received message occures.
- * [THRIFT-3881] - Travis CI builds are failing due to docker failures (three retries, and gives up)
- * [THRIFT-3937] - Cannot compile 0.10.0 development tip with gcc-4.6.x
- * [THRIFT-3964] - Unsupported mechanism type ????? due to dependency on default OS-dependent charset
- * [THRIFT-3038] - Use of volatile in cpp library
- * [THRIFT-3301] - Java generated code uses imports that can lead to class name collisions with IDL defined types
- * [THRIFT-3348] - PHP TCompactProtocol bool&int64 readvalue bug
- * [THRIFT-3955] - TThreadedServer Memory Leak
- * [THRIFT-3829] - Thrift does not install Python Libraries if Twisted is not installed
- * [THRIFT-3932] - C++ ThreadManager has a rare termination race
- * [THRIFT-3828] - cmake fails when Boost_INCLUDE_DIRS (and other variables passed to include_directories()) is empty
- * [THRIFT-3958] - CMake WITH_MT option for windows static runtime linking does not support the cmake build type RelWithDebInfo
- * [THRIFT-3957] - TConnectedClient does not disconnect from clients when their timeout is reached.
- * [THRIFT-3953] - TSSLSocket::close should handle exceptions from waitForEvent because it is called by the destructor.
- * [THRIFT-3977] - PHP extension creates undefined values when deserializing sets
- * [THRIFT-3947] - sockaddr type isn't always large enough for the return of getsockname
- * [THRIFT-2755] - ThreadSanitizer reports data race in ThreadManager::Impl::addWorker
- * [THRIFT-3948] - errno is not the correct method of getting the error in windows
- * [THRIFT-4008] - broken ci due to upstream dependency versioning break
- * [THRIFT-3999] - Fix Debian & Ubuntu package dependencies
- * [THRIFT-3886] - PHP cross test client returns 0 even when failing
- * [THRIFT-3997] - building thrift libs does not support new openssl
-
-## Documentation
- * [THRIFT-3867] - Specify BinaryProtocol and CompactProtocol
-
-## Epic
- * [THRIFT-3049] - As an iOS developer, I want a generator and library that produces Swift code
- * [THRIFT-2336] - UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
-
-## Improvement
- * [THRIFT-1867] - Python client/server should support client-side certificates.
- * [THRIFT-1313] - c_glib compact support
- * [THRIFT-1385] - make install doesn't install java library in the setted folder
- * [THRIFT-1437] - Update RPM spec
- * [THRIFT-847] - Test Framework harmonization across all languages
- * [THRIFT-819] - add Enumeration for protocol, transport and server types
- * [THRIFT-3927] - Emit an error instead of throw an error in the async callback
- * [THRIFT-3931] - TSimpleServer: If process request encounter UNKNOWN_METHOD, don't close transport.
- * [THRIFT-3934] - Automatically resolve OpenSSL binary version on Windows CI
- * [THRIFT-3918] - Run subset of make cross
- * [THRIFT-3908] - Remove redundant dependencies from Dockerfile
- * [THRIFT-3907] - Skip Docker image build on CI when unchanged
- * [THRIFT-3868] - Java struct equals should do identity check before field comparison
- * [THRIFT-3849] - Port Go serializer and deserializer to dart
- * [THRIFT-2989] - Complete CMake build for Apache Thrift
- * [THRIFT-2980] - ThriftMemoryBuffer doesn't have a constructor option to take an existing buffer
- * [THRIFT-2856] - refactor erlang basic transports and unify interfaces
- * [THRIFT-2877] - Optimize generated hashCode
- * [THRIFT-2869] - JSON: run schema validation from tests
- * [THRIFT-3112] - [Java] AsyncMethodCallback should be typed in generated AsyncIface
- * [THRIFT-3263] - PHP jsonSerialize() should cast scalar types
- * [THRIFT-2905] - Cocoa compiler should have option to produce "modern" Objective-C
- * [THRIFT-2821] - Enable the use of custom HTTP-Header in the Transport
- * [THRIFT-2093] - added the ability to set compression level in C++ zlib transport
- * [THRIFT-2089] - Compiler ignores duplicate typenames
- * [THRIFT-2056] - Moved all #include config.h statements to #include <thrift/config.h>
- * [THRIFT-2031] - Make SO_KEEPALIVE configurable for C++ lib
- * [THRIFT-2021] - Improve large binary protocol string performance
- * [THRIFT-2028] - Cleanup threading headers / libraries
- * [THRIFT-2014] - Change C++ lib includes to use <namespace/> style throughout
- * [THRIFT-2312] - travis.yml: build everything
- * [THRIFT-1915] - Multiplexing Services
- * [THRIFT-1736] - Visual Studio top level project files within msvc
- * [THRIFT-1735] - integrate tutorial into regular build
- * [THRIFT-1533] - Make TTransport should be Closeable
- * [THRIFT-35] - Move language tests into their appropriate library directory
- * [THRIFT-1079] - Support i64 in AS3
- * [THRIFT-1108] - SSL support for the Ruby library
- * [THRIFT-3856] - update debian package deependencies
- * [THRIFT-3833] - haxe http server implementation (by embeding into php web server)
- * [THRIFT-3839] - Performance issue with big message deserialization using php extension
- * [THRIFT-3820] - Erlang: Detect OTP >= 18 to use new time correction
- * [THRIFT-3816] - Reduce docker build duration on Travis-CI
- * [THRIFT-3815] - Put appveyor dependency versions to one place
- * [THRIFT-3788] - Compatibility improvements and Win64 support
- * [THRIFT-3792] - Timeouts for anonymous pipes should be configurable
- * [THRIFT-3794] - Split Delphi application, protocol and transport exception subtypes into separate exceptions
- * [THRIFT-3774] - The generated code should have exception_names meta info
- * [THRIFT-3762] - Fix build warnings for deprecated Thrift "byte" fields
- * [THRIFT-3756] - Improve requiredness documentation
- * [THRIFT-3761] - Add debian package for Python3
- * [THRIFT-3742] - haxe php cli support
- * [THRIFT-3733] - Socket timeout improvements
- * [THRIFT-3728] - http transport for thrift-lua
- * [THRIFT-3905] - Dart compiler does not initialize bool, int, and double properties
- * [THRIFT-3911] - Loosen Ruby dev dependency version requirements
- * [THRIFT-3906] - Run C# tests with make check
- * [THRIFT-3900] - Add Python SSL flags
- * [THRIFT-3897] - Provide meaningful exception type based on WebExceptionStatus in case of timeout
- * [THRIFT-3808] - Missing `DOUBLE` in thrift type enumeration
- * [THRIFT-3803] - Remove "file" attribute from XML generator
- * [THRIFT-3660] - Add V4 mapped address to test client cert's altname
- * [THRIFT-3661] - Use https to download meck in erlang test build
- * [THRIFT-3659] - Check configure result of CMake on CI
- * [THRIFT-3667] - Add TLS SNI support to clients
- * [THRIFT-3651] - Make backports.match_hostname and ipaddress optional
- * [THRIFT-3666] - Build D tutorial as part of Autotools build
- * [THRIFT-3665] - Add D libevent and OpenSSL to docker images
- * [THRIFT-3664] - Remove md5.c
- * [THRIFT-3662] - Add Haskell to debian docker image
- * [THRIFT-3711] - Add D to cross language test
- * [THRIFT-3691] - Run flake8 Python style check on Travis-CI
- * [THRIFT-3692] - (Re)enable Appveyor C++ and Python build
- * [THRIFT-3677] - Improve CMake Java build
- * [THRIFT-3679] - Add stdout log to testBinary in Java test server
- * [THRIFT-3718] - Reduce size of docker image for build environment
- * [THRIFT-3698] - [Travis-CI] Introduce retry to apt commands
- * [THRIFT-3127] - switch -recurse to --recurse and reserve -r
- * [THRIFT-3087] - Pass on errors like "connection closed"
- * [THRIFT-3240] - Thrift Python client should support subjectAltName and wildcard certs in TSSLSocket
- * [THRIFT-3213] - make cross should indicate when it skips a known failing test
- * [THRIFT-3208] - Fix Visual Studio solution build failure due to missing source
- * [THRIFT-3186] - Add TServerHTTP to Go library
- * [THRIFT-2342] - Add __FILE__ and __LINE__ to Thrift C++ excpetions
- * [THRIFT-3372] - Add dart generator to Visual Studio project
- * [THRIFT-3366] - ThriftTest to implement standard return values
- * [THRIFT-3402] - Provide a perl Unix Socket implementation
- * [THRIFT-3361] - Improve C# library
- * [THRIFT-3393] - Introduce i8 to provide consistent set of Thrift IDL integer types
- * [THRIFT-3339] - Support for database/sql
- * [THRIFT-3565] - C++: T[Async]Processor::getEventHandler() should be declared as const member functions
- * [THRIFT-3563] - C++/Qt: removed usage of macro QT_PREPEND_NAMESPACE as it isn't consequently used for all references to Qt types.
- * [THRIFT-3562] - Removed unused TAsyncProcessor::getAsyncServer()
- * [THRIFT-3561] - C++/Qt: make use of Q_DISABLE_COPY() to get rid of copy ctor and assignment operator
- * [THRIFT-3556] - c_glib file descriptor transport
- * [THRIFT-3544] - Make cross test fail when server process died unexpectedly
- * [THRIFT-3540] - Make python tutorial more in line with PEP8
- * [THRIFT-3535] - Dart generator argument to produce a file structure usable in parent library
- * [THRIFT-3505] - Enhance Python TSSLSocket
- * [THRIFT-3506] - Eliminate old style classes from library code
- * [THRIFT-3503] - Enable py:utf8string by default
- * [THRIFT-3499] - Add package_prefix to python generator
- * [THRIFT-3495] - Minor enhancements and fixes for cross test
- * [THRIFT-3486] - Java generated `getFieldValue` is incompatible with `setFieldValue` for binary values.
- * [THRIFT-3484] - Consolidate temporary buffers in Java's TCompactProtocol
- * [THRIFT-3516] - Add feature test for THeader TBinaryProtocol interop
- * [THRIFT-3515] - Python 2.6 compatibility and test on CI
- * [THRIFT-3514] - PHP 7 compatible version of binary protocol
- * [THRIFT-3469] - Docker: Debian support
- * [THRIFT-3416] - Retire old "xxx_namespace" declarations from the IDL
- * [THRIFT-3426] - Align autogen comment in XSD
- * [THRIFT-3424] - Add CMake android build option
- * [THRIFT-3439] - Run make cross using Python3 when available
- * [THRIFT-3440] - Python make check takes too much time
- * [THRIFT-3441] - Stabilize Travis-CI builds
- * [THRIFT-3431] - Avoid "schemes" HashMap lookups during struct reads/writes
- * [THRIFT-3432] - Add a TByteBuffer transport to the Java library
- * [THRIFT-3438] - Enable py:new_style by default
- * [THRIFT-3405] - Go THttpClient misuses http.Client objects
- * [THRIFT-3614] - Improve logging of test_sslsocket.py
- * [THRIFT-3647] - Fix php extension build warnings
- * [THRIFT-3642] - Speed up cross test runner
- * [THRIFT-3637] - Implement compact protocol for dart
- * [THRIFT-3613] - Port Python C extension to Python 3
- * [THRIFT-3612] - Add Python C extension for compact protocol
- * [THRIFT-3611] - Add --regex filter to cross test runner
- * [THRIFT-3631] - JSON protocol implementation for Lua
- * [THRIFT-3609] - Remove or replace TestPortFixture.h
- * [THRIFT-3605] - Have the compiler complain about invalid arguments and options
- * [THRIFT-3596] - Better conformance to PEP8
- * [THRIFT-3585] - Compact protocol implementation for Lua
- * [THRIFT-3582] - Erlang libraries should have service metadata
- * [THRIFT-3579] - Introduce retry to make cross
- * [THRIFT-3306] - Java: TBinaryProtocol: Use 1 temp buffer instead of allocating 8
- * [THRIFT-3910] - Do not invoke pip as part of build process
- * [THRIFT-1857] - Python 3.X Support
- * [THRIFT-1944] - Binding to zero port
- * [THRIFT-3954] - Enable the usage of structs called "Object" in Java
- * [THRIFT-3981] - Enable analyzer strong mode in Dart library
- * [THRIFT-3998] - Document ability to add custom tags to thrift structs
- * [THRIFT-4006] - Add a removeEventListener method on TSocket
-
-## New Feature
- * [THRIFT-640] - Support deprecation
- * [THRIFT-948] - SSL socket support for PHP
- * [THRIFT-764] - add Support for Vala language
- * [THRIFT-3046] - Allow PSR4 class loading for generated classes (PHP)
- * [THRIFT-2113] - Erlang SSL Socket Support
- * [THRIFT-1482] - Unix domain socket support under PHP
- * [THRIFT-519] - Support collections of types without having to explicitly define it
- * [THRIFT-468] - Rack Middleware Application for Rails
- * [THRIFT-1708] - Add event handlers for processor events
- * [THRIFT-3834] - Erlang namespacing and exception metadata
- * [THRIFT-2510] - Implement TNonblockingServer's ability to listen on unix domain sockets
- * [THRIFT-3397] - Implement TProcessorFactory in C# to enable per-client processors
- * [THRIFT-3523] - XML Generator
- * [THRIFT-3510] - Add HttpTaskAsyncHandler implementation
- * [THRIFT-3318] - PHP: SimpleJSONProtocol Implementation
- * [THRIFT-3299] - Dart language bindings in Thrift
- * [THRIFT-2835] - Add possibility to distribute generators separately from thrift core, and load them dynamically
- * [THRIFT-184] - Add OSGi Manifest headers to the libthrift java library to be able to use Thrift in the OSGi runtime
- * [THRIFT-141] - If a required field is not present on serialization, throw an exception
- * [THRIFT-1891] - Add Windows ALPC transport which is right counterpart of Unix domain sockets
-
-## Question
- * [THRIFT-1808] - The Thrift struct should be considered self-contained?
- * [THRIFT-2895] - Tutorial cpp
- * [THRIFT-3860] - Elephant-bird application Test fails for Thrift
- * [THRIFT-3811] - HTTPS Support for C++ applications
- * [THRIFT-3509] - "make check" error
-
-## Story
- * [THRIFT-3452] - .travis.yml: Migrating from legacy to container-based infrastructure
-
-## Sub-task
- * [THRIFT-1811] - ruby tutorial as part of the regular build
- * [THRIFT-2779] - PHP TJSONProtocol encode unicode into UCS-4LE which can't be parsed by other language bindings
- * [THRIFT-2110] - Erlang: Support for Multiplexing Services on any Transport, Protocol and Server
- * [THRIFT-3852] - A Travis-CI job fails with "write error"
- * [THRIFT-3740] - Fix haxelib.json classpath
- * [THRIFT-3653] - incorrect union serialization
- * [THRIFT-3652] - incorrect serialization of optionals
- * [THRIFT-3655] - incorrect union serialization
- * [THRIFT-3654] - incorrect serialization of optionals
- * [THRIFT-3656] - incorrect serialization of optionals
- * [THRIFT-3699] - Fix integer limit symbol includes in Python C extension
- * [THRIFT-3693] - Fix include issue in C++ TSSLSocketInterruptTest on Windows
- * [THRIFT-3694] - [Windows] Disable tests of a few servers that are not supported
- * [THRIFT-3696] - Install pip to CentOS Docker images to fix Python builds
- * [THRIFT-3638] - Fix haxelib.json
- * [THRIFT-3251] - Add http transport for server to Go lib
- * [THRIFT-2424] - Recursive Types
- * [THRIFT-2423] - THeader
- * [THRIFT-2413] - Python: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
- * [THRIFT-2409] - Java: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
- * [THRIFT-2412] - D: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
- * [THRIFT-2411] - C++: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
- * [THRIFT-2410] - JavaMe: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
- * [THRIFT-2668] - TestSuite: detailed result on passed tests by feature
- * [THRIFT-2659] - python Test Server fails when throwing TException
- * [THRIFT-3398] - Add CMake build for Haskell library and tests
- * [THRIFT-3396] - DART: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
- * [THRIFT-3364] - Fix ruby binary field encoding in TJSONProtocol
- * [THRIFT-3381] - Fix for misc. codegen issues with THRIFT-2905
- * [THRIFT-3573] - No rule to make target `../../../test/c_glib/src/.deps/testthrifttest-thrift_test_handler.Po'.
- * [THRIFT-3572] - "Unable to determine the behavior of a signed right shift"
- * [THRIFT-3542] - Add length limit support to Java test server
- * [THRIFT-3537] - Remove the (now obsolete) csharp:asyncctp flag
- * [THRIFT-3532] - Add configurable string and container read size limit to Python protocols
- * [THRIFT-3531] - Create cross lang feature test for string and container read length limit
- * [THRIFT-3482] - Haskell JSON protocol does not encode binary field as Base64
- * [THRIFT-3425] - Minor fixes + simplification for CentOS Dockerfile
- * [THRIFT-3442] - Run CMake tests on Appveyor
- * [THRIFT-3409] - NodeJS binary field issues
- * [THRIFT-3621] - Fix lib/cpp/test/SecurityTest.cpp to use ephemeral ports
- * [THRIFT-3628] - Fix lib/cpp/test/TServerIntegrationTest.cpp to use ephemeral ports
- * [THRIFT-3625] - Kill unused #include "TestPortFixture.h" in lib/cpp/test/TServerTransportTest.cpp.
- * [THRIFT-3646] - Fix Python extension build warnings
- * [THRIFT-3626] - Fix lib/cpp/test/TSocketInterruptTest.cpp to use ephemeral ports.
- * [THRIFT-3624] - Fix lib/cpp/test/TServerSocketTest.cpp to use ephemeral ports
- * [THRIFT-3623] - Fix Fix cpp/lib/test/TSSLSocketInterruptTest.cpp to use ephemeral ports
- * [THRIFT-3592] - Add basic test client
- * [THRIFT-3980] - add TExtendedBinaryProtocol.java
-
-## Task
- * [THRIFT-1801] - Sync up TApplicationException codes across languages and thrift implementations
- * [THRIFT-1259] - Automate versioning
-
-## Test
- * [THRIFT-3400] - Add Erlang to cross test
- * [THRIFT-3504] - Fix FastbinaryTest.py
-
-## Wish
- * [THRIFT-3923] - Maybe remove Aereo from the "Powered by" list
- * [THRIFT-2149] - Add an option to disable the generation of default operators
-
-
-
-Thrift 0.9.3
---------------------------------------------------------------------------------
-## Bug
- * [THRIFT-2441] - Cannot shutdown TThreadedServer when clients are still connected
- * [THRIFT-2465] - TBinaryProtocolT breaks if copied/moved
- * [THRIFT-2474] - thrift.h causes a compile failure
- * [THRIFT-2540] - Running configure from outside the source directory fails
- * [THRIFT-2598] - Add check for minimum Go version to configure.ac
- * [THRIFT-2647] - compiler-hs: don't decapitalize field names, do decapitalize argument bindings
- * [THRIFT-2773] - Generated Java code for 'oneway' methods is incorrect.
- * [THRIFT-2789] - TNonblockingServer leaks socket FD's under load
- * [THRIFT-2682] - TThreadedServer leaks per-thread memory
- * [THRIFT-2674] - JavaScript: declare Accept: and Content-Type: in request
- * [THRIFT-3078] - TNonblockingServerSocket's logger is not named after TNonblockingServerSocket
- * [THRIFT-3077] - C++ TFileTransport ignores return code from ftruncate
- * [THRIFT-3067] - C++ cppcheck performance related warnings
- * [THRIFT-3066] - C++ TDenseProtocol assert modifies instead of checks
- * [THRIFT-3071] - bootstrap.sh on Ubuntu 12.04 (Precise) automake error
- * [THRIFT-3069] - C++ TServerSocket leaks socket on fcntl get or set flags error
- * [THRIFT-3079] - TNonblockingServerSocket's logger is not named after TNonblockingServerSocket
- * [THRIFT-3080] - C++ TNonblockingServer connection leak while accept huge number connections.
- * [THRIFT-3086] - C++ Valgrind Error Cleanup
- * [THRIFT-3085] - thrift_reconnecting_client never try to reconnect
- * [THRIFT-3123] - Missing include in compiler/cpp/src/main.h breaks build in some environments
- * [THRIFT-3125] - Fix the list of exported headers in automake input
- * [THRIFT-3126] - PHP JSON serializer converts empty or int-indexed maps to lists
- * [THRIFT-3132] - Properly format date in Java @Generated annotations
- * [THRIFT-3137] - Travis build hangs after failure
- * [THRIFT-3138] - "make check" parallel execution is underministic
- * [THRIFT-3139] - JS library test is flaky
- * [THRIFT-3140] - ConcurrentModificationException is thrown by JavaScript test server
- * [THRIFT-3124] - Some signed/unsigned warnings while building compiler
- * [THRIFT-3128] - Go generated code produces name collisions between services
- * [THRIFT-3146] - Graphviz generates function name collisions between services
- * [THRIFT-3147] - Segfault while receiving data
- * [THRIFT-3148] - Markdown links to coding_standards are dead
- * [THRIFT-3090] - cmake build is broken on MacOSX
- * [THRIFT-3097] - cmake targets unconditionally depend on optional libraries
- * [THRIFT-3094] - master as of 2015-APR-13 fails -DBOOST_THREADS cmake build
- * [THRIFT-3099] - cmake build is broken on FreeBSD
- * [THRIFT-3089] - Assigning default ENUM values results in non-compilable java code if java namespace is not defined
- * [THRIFT-3093] - mingw compile fixes for c++ library 0.9.2
- * [THRIFT-3098] - Thrift does not pretty print binary typedefs the way it does binary fields
- * [THRIFT-3091] - c_glib service method should return result from handler method
- * [THRIFT-3088] - TThreadPoolServer with Sasl auth may leak CLOSE_WAIT socket
- * [THRIFT-3109] - Cross test log file cannot be browsed when served in HTTP server
- * [THRIFT-3113] - m4 C++11 macro issue
- * [THRIFT-3105] - C++ libthriftnb library on Windows build failure
- * [THRIFT-3115] - Uncompileable code due to name collision with predefined used types
- * [THRIFT-3117] - Java TSSLTransportFactory can't load certificates within JAR archive
- * [THRIFT-3102] - could not make check for Go Library
- * [THRIFT-3120] - Minor spelling errors and an outdated URL
- * [THRIFT-3121] - Librt does not exist on OS X
- * [THRIFT-3152] - Compiler error on Mac OSX (missing #include <cstdlib>)
- * [THRIFT-3162] - make fails for dmd 2.067
- * [THRIFT-3164] - Thrift C++ library SSL socket by default allows for unsecure SSLv3 negotiation
- * [THRIFT-3168] - Fix Maven POM
- * [THRIFT-3170] - Initialism code in the Go compiler causes chaos
- * [THRIFT-3169] - Do not export thrift.TestStruct and thrift.TestEnum in thrift Go library
- * [THRIFT-3191] - Perl compiler does not add support for unexpected exception handling
- * [THRIFT-3178] - glib C does not compile
- * [THRIFT-3189] - Perl ServerSocket should allow a specific interface to be listened to
- * [THRIFT-3252] - Missing TConcurrentClientSyncInfo.h in cpp Makefile, so doesn't install
- * [THRIFT-3255] - Thrift generator doesn't exclude 'package' keyword for thrift property names breaking java builds
- * [THRIFT-3260] - multiple warnings in c_glib tutorial
- * [THRIFT-3256] - Some D test timings are too aggressive for slow machines
- * [THRIFT-3257] - warning: extra tokens at end of #endif directive
- * [THRIFT-3184] - Thrift Go leaves file descriptors open
- * [THRIFT-3203] - DOAP - please fix "Ocaml" => "OCaml"
- * [THRIFT-3210] - (uncompileable) code generated for server events while are events not enabled
- * [THRIFT-3215] - TJSONProtocol '(c++) uses "throw new" to throw exceptions instead of "throw"
- * [THRIFT-3202] - Allow HSHAServer to configure min and max worker threads separately.
- * [THRIFT-3205] - TCompactProtocol return a wrong error when the io.EOF happens
- * [THRIFT-3209] - LGPL mentioned in license file
- * [THRIFT-3197] - keepAliveTime is hard coded as 60 sec in TThreadPoolServer
- * [THRIFT-3196] - Misspelling in lua TBinaryProtocol (stirctWrite => strictWrite)
- * [THRIFT-3198] - Allow construction of TTransportFactory with a specified maxLength
- * [THRIFT-3192] - Go import paths changed in 1.4, and expired June 1
- * [THRIFT-3271] - Could not find or load main class configtest_ax_javac_and_java on some non-english systems
- * [THRIFT-3273] - c_glib: Generated code tries to convert between function and void pointers
- * [THRIFT-3264] - Fix Erlang 16 namespaced types
- * [THRIFT-3270] - reusing TNonblockingServer::TConnection cause dirty TSocket
- * [THRIFT-3267] - c_glib: "Critical" failure during unit tests
- * [THRIFT-3277] - THttpClient leaks connections if it's used for multiple requests
- * [THRIFT-3278] - NodeJS: Fix exception stack traces and names
- * [THRIFT-3279] - Fix a bug in retry_max_delay (NodeJS)
- * [THRIFT-3280] - Initialize retry variables on construction
- * [THRIFT-3283] - c_glib: Tutorial server always exits with warning
- * [THRIFT-3284] - c_glib: Empty service produces unused-variable warning
- * [THRIFT-1925] - c_glib generated code does not compile
- * [THRIFT-1849] - after transport->open() opens isOpen returns true and next open() goes thru when it shall not
- * [THRIFT-1866] - java compiler generates non-compiling code with const's defined in a thrift when name includes non-identifier chars
- * [THRIFT-1938] - FunctionRunner.h -- uses wrong path for Thread.h when installed
- * [THRIFT-1844] - Password string not cleared
- * [THRIFT-2004] - Thrift::Union violates :== method contract and crashes
- * [THRIFT-2073] - Thrift C++ THttpClient error: cannot refill buffer
- * [THRIFT-2127] - Autoconf scripting does not properly account for cross-compile
- * [THRIFT-2180] - Integer types issues in Cocoa lib on ARM64
- * [THRIFT-2189] - Go needs "isset" to fully support "union" type (and optionals)
- * [THRIFT-2192] - autotools on Redhat based systems
- * [THRIFT-2546] - cross language tests fails at 'TestMultiException' when using nodejs server
- * [THRIFT-2547] - nodejs servers and clients fails to connect with cpp using compact protocol
- * [THRIFT-2548] - Nodejs servers and clients does not work properly with -ssl
- * [THRIFT-1471] - toString() does not print ByteBuffer values when nested in a List
- * [THRIFT-1201] - getaddrinfo resource leak
- * [THRIFT-615] - TThreadPoolServer doesn't call task_done after pulling tasks from it's clients queue
- * [THRIFT-162] - Thrift structures are unhashable, preventing them from being used as set elements
- * [THRIFT-810] - Crashed client on TSocket::close under loads
- * [THRIFT-557] - charset problem with file Autogenerated by Thrift
- * [THRIFT-233] - IDL doesn't support negative hex literals
- * [THRIFT-1649] - contrib/zeromq does not build in 0.8.0
- * [THRIFT-1642] - Miscalculation lead to throw unexpected "TTransportException::TIMED_OUT"(or called "EAGAIN (timed out)") exception
- * [THRIFT-1587] - TSocket::setRecvTimeout error
- * [THRIFT-1248] - pointer subtraction in TMemoryBuffer relies on undefined behavior
- * [THRIFT-1774] - Sasl Transport client would hang when trying to connect non-sasl transport server
- * [THRIFT-1754] - RangeError in buffer handling
- * [THRIFT-1618] - static structMap in FieldMetaData is not thread safe and can lead to deadlocks
- * [THRIFT-2335] - thrift incompatibility with py:tornado as server, java as client
- * [THRIFT-2803] - TCP_DEFER_ACCEPT not supported with domain sockets
- * [THRIFT-2799] - Build Problem(s): ld: library not found for -l:libboost_unit_test_framework.a
- * [THRIFT-2801] - C++ test suite compilation warnings
- * [THRIFT-2802] - C++ tutorial compilation warnings
- * [THRIFT-2795] - thrift_binary_protocol.c: 'dereferencing type-punned pointer will break strict-aliasing rules'
- * [THRIFT-2817] - TSimpleJSONProtocol reads beyond end of message
- * [THRIFT-2826] - html:standalone sometimes ignored
- * [THRIFT-2829] - Support haxelib installation via github
- * [THRIFT-2828] - slightly wrong help screen indent
- * [THRIFT-2831] - Removes dead code in web_server.js introduced in THRIFT-2819
- * [THRIFT-2823] - All JS-tests are failing when run with grunt test
- * [THRIFT-2827] - Thrift 0.9.2 fails to compile on Yosemite due to tr1/functional include in ProcessorTest.cpp
- * [THRIFT-2843] - Automake configure.ac has possible typo related to Java
- * [THRIFT-2813] - multiple haxe library fixes/improvements
- * [THRIFT-2825] - Supplying unicode to python Thrift client can cause next request arguments to get overwritten
- * [THRIFT-2840] - Cabal file points to LICENSE file outside the path of the Haskell project.
- * [THRIFT-2818] - Trailing commas in array
- * [THRIFT-2830] - Clean up ant warnings in tutorial dir
- * [THRIFT-2842] - Erlang thrift client has infinite timeout
- * [THRIFT-2810] - Do not leave the underlying ServerSocket open if construction of TServerSocket fails
- * [THRIFT-2812] - Go server adding redundant buffering layer
- * [THRIFT-2839] - TFramedTransport read bug
- * [THRIFT-2844] - Nodejs support broken when running under Browserify
- * [THRIFT-2814] - args/result classes not found when no namespace is set
- * [THRIFT-2847] - function IfValue() is a duplicate of System.StrUtils.IfThen
- * [THRIFT-2848] - certain Delphi tests do not build if TypeRegistry is used
- * [THRIFT-2854] - Go Struct writer and reader looses important error information
- * [THRIFT-2858] - Enable header field case insensitive match in THttpServer
- * [THRIFT-2857] - C# generator creates uncompilable code for struct constants
- * [THRIFT-2860] - Delphi server closes connection on unexpected exceptions
- * [THRIFT-2868] - Enhance error handling in the Go client
- * [THRIFT-2879] - TMemoryBuffer: using lua string in wrong way
- * [THRIFT-2851] - Remove strange public Peek() from Go transports
- * [THRIFT-2852] - Better Open/IsOpen/Close behavior for StreamTransport.
- * [THRIFT-2871] - Missing semicolon in thrift.js
- * [THRIFT-2872] - ThreadManager deadlock for task expiration
- * [THRIFT-2881] - Handle errors from Accept() correctly
- * [THRIFT-2849] - Spell errors reported by codespell tool
- * [THRIFT-2870] - C++ TJSONProtocol using locale dependent formatting
- * [THRIFT-2882] - Lua Generator: using string.len funtion to get struct(map,list,set) size
- * [THRIFT-2864] - JSON generator missing from Visual Studio build project
- * [THRIFT-2878] - Go validation support of required fields
- * [THRIFT-2873] - TPipe and TPipeServer don't compile on Windows with UNICODE enabled
- * [THRIFT-2888] - import of <limits> is missing in JSON generator
- * [THRIFT-2900] - Python THttpClient does not reset socket timeout on exception
- * [THRIFT-2907] - 'ntohll' macro redefined
- * [THRIFT-2884] - Map does not serialize correctly for JSON protocol in Go library
- * [THRIFT-2887] - --with-openssl configure flag is ignored
- * [THRIFT-2894] - PHP json serializer skips maps with int/bool keys
- * [THRIFT-2904] - json_protocol_test.go fails
- * [THRIFT-2906] - library not found for -l:libboost_unit_test_framework.a
- * [THRIFT-2890] - binary data may lose bytes with JSON transport under specific circumstances
- * [THRIFT-2891] - binary data may cause a failure with JSON transport under specific circumstances
- * [THRIFT-2901] - Fix for generated TypeScript functions + indentation of JavaScript maps
- * [THRIFT-2916] - make check fails for D language
- * [THRIFT-2918] - Race condition in Python TProcessPoolServer test
- * [THRIFT-2920] - Erlang Thrift test uses wrong IDL file
- * [THRIFT-2922] - $TRIAL is used with Python tests but not tested accordingly
- * [THRIFT-2912] - Autotool build for C++ Qt library is invalid
- * [THRIFT-2914] - explicit dependency to Lua5.2 fails on some systems
- * [THRIFT-2910] - libevent is not really optional
- * [THRIFT-2911] - fix c++ version zeromq transport, the old version cannot work
- * [THRIFT-2915] - Lua generator missing from Visual Studio build project
- * [THRIFT-2917] - "make clean" breaks test/c_glib
- * [THRIFT-2919] - Haxe test server timeout too large
- * [THRIFT-2923] - JavaScript client assumes a message being written
- * [THRIFT-2924] - TNonblockingServer crashes when user-provided event_base is used
- * [THRIFT-2925] - CMake build does not work with OpenSSL nor anything installed in non-system location
- * [THRIFT-2931] - Access to undeclared static property: Thrift\Protocol\TProtocol::$TBINARYPROTOCOLACCELERATED
- * [THRIFT-2893] - CMake build fails with boost thread or std thread
- * [THRIFT-2902] - Generated c_glib code does not compile with clang
- * [THRIFT-2903] - Qt4 library built with CMake does not work
- * [THRIFT-2942] - CSharp generate invalid code for property named read or write
- * [THRIFT-2932] - Node.js Thrift connection libraries throw Exceptions into event emitter
- * [THRIFT-2933] - v0.9.2: doubles encoded in node with compact protocol cannot be decoded by python
- * [THRIFT-2934] - createServer signature mismatch
- * [THRIFT-2981] - IDL with no namespace produces unparsable PHP
- * [THRIFT-2999] - Addition of .gitattributes text auto in THRIFT-2724 causes modified files on checkout
- * [THRIFT-2949] - typo in compiler/cpp/README.md
- * [THRIFT-2957] - warning: source file %s is in a subdirectory, but option 'subdir-objects' is disabled
- * [THRIFT-2953] - TNamedPipeServerTransport is not Stop()able
- * [THRIFT-2962] - Docker Thrift env for development and testing
- * [THRIFT-2971] - C++ test and tutorial parallel build is unstable
- * [THRIFT-2972] - Missing backslash in lib/cpp/test/Makefile.am
- * [THRIFT-2951] - Fix Erlang name conflict test
- * [THRIFT-2955] - Using list of typedefs does not compile on Go
- * [THRIFT-2960] - namespace regression for Ruby
- * [THRIFT-2959] - nodejs: fix binary unit tests
- * [THRIFT-2966] - nodejs: Fix bad references to TProtocolException and TProtocolExceptionType
- * [THRIFT-2970] - grunt-jsdoc fails due to dependency issues
- * [THRIFT-3001] - C# Equals fails for binary fields (byte[])
- * [THRIFT-3003] - Missing LICENSE file prevents package from being installed
- * [THRIFT-3008] - Node.js server does not fully support exception
- * [THRIFT-3007] - Travis build is broken because of directory conflict
- * [THRIFT-3009] - TSSLSocket does not use the correct hostname (breaks certificate checks)
- * [THRIFT-3011] - C# test server testException() not implemented according to specs
- * [THRIFT-3012] - Timing problems in NamedPipe implementation due to unnecessary open/close
- * [THRIFT-3019] - Golang generator missing docstring for structs
- * [THRIFT-3021] - Service remote tool does not import stub package with package prefix
- * [THRIFT-3026] - TMultiplexedProcessor does not have a constructor
- * [THRIFT-3028] - Regression caused by THRIFT-2180
- * [THRIFT-3017] - order of map key/value types incorrect for one CTOR
- * [THRIFT-3020] - Cannot compile thrift as C++03
- * [THRIFT-3024] - User-Agent "BattleNet" used in some Thrift library files
- * [THRIFT-3047] - Uneven calls to indent_up and indent_down in Cocoa generator
- * [THRIFT-3048] - NodeJS decoding of I64 is inconsistent across protocols
- * [THRIFT-3043] - go compiler generator uses non C++98 code
- * [THRIFT-3044] - Docker README.md paths to Dockerfiles are incorrect
- * [THRIFT-3040] - bower.json wrong "main" path
- * [THRIFT-3051] - Go Thrift generator creates bad go code
- * [THRIFT-3057] - Java compiler build is broken
- * [THRIFT-3061] - C++ TSSLSocket shutdown delay/vulnerability
- * [THRIFT-3062] - C++ TServerSocket invalid port number (over 999999) causes stack corruption
- * [THRIFT-3065] - Update libthrift dependencies (slf4j, httpcore, httpclient)
- * [THRIFT-3244] - TypeScript: fix namespace of included types
- * [THRIFT-3246] - Reduce the number of trivial warnings in Windows C++ CMake builds
- * [THRIFT-3224] - Fix TNamedPipeServer unpredictable behavior on accept
- * [THRIFT-3230] - Python compiler generates wrong code if there is function throwing a typedef of exception with another namespace
- * [THRIFT-3236] - MaxSkipDepth never checked
- * [THRIFT-3239] - Limit recursion depth
- * [THRIFT-3241] - fatal error: runtime: cannot map pages in arena address space
- * [THRIFT-3242] - OSGi Import-Package directive is missing the Apache HTTP packages
- * [THRIFT-3234] - Limit recursion depth
- * [THRIFT-3222] - TypeScript: Generated Enums are quoted
- * [THRIFT-3229] - unexpected Timeout exception when desired bytes are only partially available
- * [THRIFT-3231] - CPP: Limit recursion depth to 64
- * [THRIFT-3235] - Limit recursion depth
- * [THRIFT-3175] - fastbinary.c python deserialize can cause huge allocations from garbage
- * [THRIFT-3176] - Union incorrectly implements ==
- * [THRIFT-3177] - Fails to run rake test
- * [THRIFT-3180] - lua plugin: framed transport do not work
- * [THRIFT-3179] - lua plugin cant connect to remote server because function l_socket_create_and_connect always bind socket to localhost
- * [THRIFT-3248] - TypeScript: additional comma in method signature without parameters
- * [THRIFT-3302] - Go JSON protocol should encode Thrift byte type as signed integer string
- * [THRIFT-3297] - c_glib: an abstract base class is not generated
- * [THRIFT-3294] - TZlibTransport for Java does not write data correctly
- * [THRIFT-3296] - Go cross test does not conform to spec
- * [THRIFT-3295] - C# library does not build on Mono 4.0.2.5 or later
- * [THRIFT-3293] - JavaScript: null values turn into empty structs in constructor
- * [THRIFT-3310] - lib/erl/README.md has incorrect formatting
- * [THRIFT-3319] - CSharp tutorial will not build using the *.sln
- * [THRIFT-3335] - Ruby server does not handle processor exception
- * [THRIFT-3338] - Stray underscore in generated go when service name starts with "New"
- * [THRIFT-3324] - Update Go Docs for pulling all packages
- * [THRIFT-3345] - Clients blocked indefinitely when a java.lang.Error is thrown
- * [THRIFT-3332] - make dist fails on clean build
- * [THRIFT-3326] - Tests do not compile under *BSD
- * [THRIFT-3334] - Markdown notation of protocol spec is malformed
- * [THRIFT-3331] - warning: ‘etype’ may be used uninitialized in this function
- * [THRIFT-3349] - Python server does not handle processor exception
- * [THRIFT-3343] - Fix haskell README
- * [THRIFT-3340] - Python: enable json tests again
- * [THRIFT-3311] - Top level README.md has incorrect formmating
- * [THRIFT-2936] - Minor memory leak in SSL
- * [THRIFT-3290] - Using from in variable names causes the generated Python code to have errors
- * [THRIFT-3225] - Fix TPipeServer unpredictable behavior on interrupt()
- * [THRIFT-3354] - Fix word-extraction substr bug in initialism code
- * [THRIFT-2006] - TBinaryProtocol message header call name length is not validated and can be used to core the server
- * [THRIFT-3329] - C++ library unit tests don't compile against the new boost-1.59 unit test framework
- * [THRIFT-2630] - windows7 64bit pc. ipv4 and ipv6 pc.can't use
- * [THRIFT-3336] - Thrift generated streaming operators added in 0.9.2 cannot be overridden
- * [THRIFT-2681] - Core of unwind_cleanup
- * [THRIFT-3317] - cpp namespace org.apache issue appears in 0.9
-
-## Documentation
- * [THRIFT-3286] - Apache Ant is a necessary dependency
-
-## Improvement
- * [THRIFT-227] - Byte[] in collections aren't pretty printed like regular binary fields
- * [THRIFT-2744] - Vagrantfile for Centos 6.5
- * [THRIFT-2644] - Haxe support
- * [THRIFT-2756] - register Media Type @ IANA
- * [THRIFT-3076] - Compatibility with Haxe 3.2.0
- * [THRIFT-3081] - C++ Consolidate client processing loops in TServers
- * [THRIFT-3083] - C++ Consolidate server processing loops in TSimpleServer, TThreadedServer, TThreadPoolServer
- * [THRIFT-3084] - C++ add concurrent client limit to threaded servers
- * [THRIFT-3074] - Add compiler/cpp/lex.yythriftl.cc to gitignore.
- * [THRIFT-3134] - Remove use of deprecated "phantom.args"
- * [THRIFT-3133] - Allow "make cross" and "make precross" to run without building all languages
- * [THRIFT-3142] - Make JavaScript use downloaded libraries
- * [THRIFT-3141] - Improve logging of JavaScript test
- * [THRIFT-3144] - Proposal: make String representation of enums in generated go code less verbose
- * [THRIFT-3130] - Remove the last vestiges of THRIFT_OVERLOAD_IF from THRIFT-1316
- * [THRIFT-3131] - Consolidate suggested import path for go thrift library to git.apache.org in docs and code
- * [THRIFT-3092] - Generated Haskell types should derive Generic
- * [THRIFT-3110] - Print error log after cross test failures on Travis
- * [THRIFT-3114] - Using local temp variables to not pollute the global table
- * [THRIFT-3106] - CMake summary should give more information why a library is set to off
- * [THRIFT-3119] - Java's TThreadedSelectorServer has indistinguishable log messages in run()
- * [THRIFT-3122] - Javascript struct constructor should properly initialize struct and container members from plain js arguments
- * [THRIFT-3151] - Fix links to git-wip* - should be git.apache.org
- * [THRIFT-3167] - Windows build from source instructions need to be revised
- * [THRIFT-3155] - move contrib/mingw32-toolchain.cmake to build/cmake/
- * [THRIFT-3160] - Make generated go enums implement TextMarshaller and TextUnmarshaller interfaces
- * [THRIFT-3150] - Add an option to thrift go generator to make Read and Write methods private
- * [THRIFT-3149] - Make ReadFieldN methods in generated Go code private
- * [THRIFT-3172] - Add tutorial to Thrift web site
- * [THRIFT-3214] - Add Erlang option for using maps instead of dicts
- * [THRIFT-3201] - Capture github test artifacts for failed builds
- * [THRIFT-3266] - c_glib: Multiple compiler warnings building unit tests
- * [THRIFT-3285] - c_glib: Build library with all warnings enabled, no warnings generated
- * [THRIFT-1954] - Allow for a separate connection timeout value
- * [THRIFT-2098] - Add support for Qt5+
- * [THRIFT-2199] - Remove Dense protocol (was: move to Contrib)
- * [THRIFT-406] - C++ Test suite cleanup
- * [THRIFT-902] - socket and connect timeout in TSocket should be distinguished
- * [THRIFT-388] - Use a separate wire format for async calls
- * [THRIFT-727] - support native C++ language specific exception message
- * [THRIFT-1784] - pep-3110 compliance for exception handling
- * [THRIFT-1025] - C++ ServerSocket should inherit from Socket with the necessary Ctor to listen on connections from a specific host
- * [THRIFT-2269] - Can deploy libthrift-source.jar to maven center repository
- * [THRIFT-2804] - Pull an interface out of TBaseAsyncProcessor
- * [THRIFT-2806] - more whitespace fixups
- * [THRIFT-2811] - Make remote socket address accessible
- * [THRIFT-2809] - .gitignore update for compiler's visual project
- * [THRIFT-2846] - Expose ciphers parameter from ssl.wrap_socket()
- * [THRIFT-2859] - JSON generator: output complete descriptors
- * [THRIFT-2861] - add buffered transport
- * [THRIFT-2865] - Test case for Go: SeqId out of sequence
- * [THRIFT-2866] - Go generator source code is hard to read and maintain
- * [THRIFT-2880] - Read the network address from the listener if available.
- * [THRIFT-2875] - Typo in TDenseProtocol.h comment
- * [THRIFT-2874] - TBinaryProtocol member variable "string_buf_" is never used.
- * [THRIFT-2855] - Move contributing.md to the root of the repository
- * [THRIFT-2862] - Enable RTTI and/or build macros for generated code
- * [THRIFT-2876] - Add test for THRIFT-2526 Assignment operators and copy constructors in c++ don't copy the __isset struct
- * [THRIFT-2897] - Generate -isEqual: and -hash methods
- * [THRIFT-2909] - Improve travis build
- * [THRIFT-2921] - Make Erlang impl ready for OTP 18 release (dict/0 and set/0 are deprecated)
- * [THRIFT-2928] - Rename the erlang test_server module
- * [THRIFT-2940] - Allow installing Thrift from git as NPM module by providing package.json in top level directory
- * [THRIFT-2937] - Allow setting a maximum frame size in TFramedTransport
- * [THRIFT-2976] - nodejs: xhr and websocket support for browserify
- * [THRIFT-2996] - Test for Haxe 3.1.3 or better
- * [THRIFT-2969] - nodejs: DRY up library tests
- * [THRIFT-2973] - Update Haxe lib readme regarding Haxe 3.1.3
- * [THRIFT-2952] - Improve handling of Server.Stop()
- * [THRIFT-2964] - nodejs: move protocols and transports into separate files
- * [THRIFT-2963] - nodejs - add test coverage
- * [THRIFT-3006] - Attach 'omitempty' json tag for optional fields in Go
- * [THRIFT-3027] - Go compiler does not ensure common initialisms have consistent case
- * [THRIFT-3030] - TThreadedServer: Property for number of clientThreads
- * [THRIFT-3023] - Go compiler is a little overly conservative with names of attributes
- * [THRIFT-3018] - Compact protocol for Delphi
- * [THRIFT-3025] - Change pure Int constants into @enums (where possible)
- * [THRIFT-3031] - migrate "shouldStop" flag to TServer
- * [THRIFT-3022] - Compact protocol for Haxe
- * [THRIFT-3041] - Generate asynchronous clients for Cocoa
- * [THRIFT-3053] - Perl SSL Socket Support (Encryption)
- * [THRIFT-3247] - Generate a C++ thread-safe client
- * [THRIFT-3217] - Provide a little endian variant of the binary protocol in C++
- * [THRIFT-3223] - TypeScript: Add initial support for Enum Maps
- * [THRIFT-3220] - Option to suppress @Generated Annotation entirely
- * [THRIFT-3300] - Reimplement TZlibTransport in Java using streams
- * [THRIFT-3288] - c_glib: Build unit tests with all warnings enabled, no warnings generated
- * [THRIFT-3347] - Improve cross test servers and clients
- * [THRIFT-3342] - Improve ruby cross test client and server compatibility
- * [THRIFT-2296] - Add C++ Base class for service
- * [THRIFT-3337] - Add testBool method to cross tests
- * [THRIFT-3303] - Disable concurrent cabal jobs on Travis to avoid GHC crash
- * [THRIFT-2623] - Docker container for Thrift
- * [THRIFT-3298] - thrift endian converters may conflict with other libraries
- * [THRIFT-1559] - Provide memory pool for TBinaryProtocol to eliminate memory fragmentation
- * [THRIFT-424] - Steal ProtocolBuffers' VarInt implementation for C++
-
-## New Feature
- * [THRIFT-3070] - Add ability to set the LocalCertificateSelectionCallback
- * [THRIFT-1909] - Java: Add compiler flag to use the "option pattern" for optional fields
- * [THRIFT-2099] - Stop TThreadPoolServer with alive connections.
- * [THRIFT-123] - implement TZlibTransport in Java
- * [THRIFT-2368] - New option: reuse-objects for Java generator
- * [THRIFT-2836] - Optionally generate C++11 MoveConstructible types
- * [THRIFT-2824] - Flag to disable html escaping doctext
- * [THRIFT-2819] - Add WebsSocket client to node.js
- * [THRIFT-3050] - Client certificate authentication for non-http TLS in C#
- * [THRIFT-3292] - Implement TZlibTransport in Go
-
-## Question
- * [THRIFT-2583] - Thrift on xPC target (SpeedGoat)
- * [THRIFT-2592] - thrift server using c_glib
- * [THRIFT-2832] - c_glib: Handle string lists correctly
- * [THRIFT-3136] - thrift installation problem on mac
- * [THRIFT-3346] - c_glib: Tutorials example crashes saying Calculator.ping implementation returned FALSE but did not set an error
-
-## Sub-task
- * [THRIFT-2578] - Moving 'make cross' from test.sh to test.py
- * [THRIFT-2734] - Go coding standards
- * [THRIFT-2748] - Add Vagrantfile for Centos 6.5
- * [THRIFT-2753] - Misc. Haxe improvements
- * [THRIFT-2640] - Compact Protocol in Cocoa
- * [THRIFT-3262] - warning: overflow in implicit constant conversion in DenseProtoTest.cpp
- * [THRIFT-3194] - Can't build with go enabled. gomock SCC path incorrect.
- * [THRIFT-3275] - c_glib tutorial warnings in generated code
- * [THRIFT-1125] - Multiplexing support for the Ruby Library
- * [THRIFT-2807] - PHP Code Style
- * [THRIFT-2841] - Add comprehensive integration tests for the whole Go stack
- * [THRIFT-2815] - Haxe: Support for Multiplexing Services on any Transport, Protocol and Server
- * [THRIFT-2886] - Integrate binary type in standard Thrift cross test
- * [THRIFT-2946] - Enhance usability of cross test framework
- * [THRIFT-2967] - Add .editorconfig to root
- * [THRIFT-3033] - Perl: Support for Multiplexing Services on any Transport, Protocol and Server
- * [THRIFT-3174] - Initialism code in the Go compiler doesn't check first word
- * [THRIFT-3193] - Option to supress date value in @Generated annotation
- * [THRIFT-3305] - Missing dist files for 0.9.3 release candidate
- * [THRIFT-3341] - Add testBool methods
- * [THRIFT-3308] - Fix broken test cases for 0.9.3 release candidate
-
-## Task
- * [THRIFT-2834] - Remove semi-colons from python code generator
- * [THRIFT-2853] - Adjust comments not applying anymore after THRIFT-2852
-
-## Test
- * [THRIFT-3211] - Add make cross support for php TCompactProtocol
-
-## Wish
- * [THRIFT-2838] - TNonblockingServer can bind to port 0 (i.e., get an OS-assigned port) but there is no way to get the port number
-
-
-
-Thrift 0.9.2
---------------------------------------------------------------------------------
-## Bug
- * [THRIFT-2793] - Go compiler produces uncompilable code
- * [THRIFT-1481] - Unix domain sockets in C++ do not support the abstract namespace
- * [THRIFT-1455] - TBinaryProtocolT<Transport_>::writeString casts from size_t to uint32_t, which is not safe on 64-bit platforms
- * [THRIFT-1579] - PHP Extention - function thrift_protocol_read_binary not working from TBinarySerializer::deserialize
- * [THRIFT-1584] - Error: could not SetMinThreads in ThreadPool on single-core machines
- * [THRIFT-1614] - Thrift build from svn repo sources fails with automake-1.12
- * [THRIFT-1047] - rb_thrift_memory_buffer_write treats arg as string without check, segfaults if you pass non-string
- * [THRIFT-1639] - Java/Python: Serialization/Deserialization of double type using CompactProtocol
- * [THRIFT-1647] - NodeJS BufferedTransport does not work beyond the hello-world example
- * [THRIFT-2130] - Thrift's D library/test: parts of "make check" code do not compile with recent dmd-2.062 through dmd-2.064alpha
- * [THRIFT-2140] - Error compiling cpp tutorials
- * [THRIFT-2139] - MSVC 2012 Error - Cannot compile due to BoostThreadFactory
- * [THRIFT-2138] - pkgconfig file created with wrong include path
- * [THRIFT-2160] - Warning in thrift.h when compiling with -Wunused and NDEBUG
- * [THRIFT-2158] - Compact, JSON, and SimpleJSON protocols are not working correctly
- * [THRIFT-2167] - nodejs lib throws error if options argument isn't passed
- * [THRIFT-2288] - Go impl of Thrift JSON protocol wrongly writes/expects true/false for bools
- * [THRIFT-2147] - Thrift IDL grammar allows for dotted identifier names
- * [THRIFT-2145] - Rack and Thin are not just development dependencies
- * [THRIFT-2267] - Should be able to choose socket family in Python TSocket
- * [THRIFT-2276] - java path in spec file needs updating
- * [THRIFT-2281] - Generated send/recv code ignores errors returned by the underlying protocol
- * [THRIFT-2280] - TJSONProtocol.Flush() does not really flush the transport
- * [THRIFT-2274] - TNonblockingServer and TThreadedSelectorServer do not close their channel selectors on exit and leak file descriptors
- * [THRIFT-2265] - php library doesn't build
- * [THRIFT-2232] - IsSet* broken in Go
- * [THRIFT-2246] - Unset enum value is printed by ToString()
- * [THRIFT-2240] - thrift.vim (contrib) does not correctly handle 'union'
- * [THRIFT-2243] - TNonblockingServer in thrift crashes when TFramedTransport opens
- * [THRIFT-2230] - Cannot Build on RHEL/Centos/Amazon Linux 6.x
- * [THRIFT-2247] - Go generator doesn't deal well with map keys of type binary
- * [THRIFT-2253] - Python Tornado TTornadoServer base class change
- * [THRIFT-2261] - java: error: unmappable character for encoding ASCII
- * [THRIFT-2259] - C#: unexpected null logDelegate() pointer causes AV in TServer.serve()
- * [THRIFT-2225] - SSLContext destroy before cleanupOpenSSL
- * [THRIFT-2224] - TSSLSocket.h and TSSLServerSocket.h should use the platfromsocket too
- * [THRIFT-2229] - thrift failed to build on OSX 10.9 GM
- * [THRIFT-2227] - Thrift compiler generates spurious warnings with Xlint
- * [THRIFT-2219] - Thrift gem fails to build on OS X Mavericks with 1.9.3 rubies
- * [THRIFT-2226] - TServerSocket - keepAlive wrong initialization order
- * [THRIFT-2285] - TJsonProtocol implementation for Java doesn't allow a slash (/) to be escaped (\/)
- * [THRIFT-2216] - Extraneous semicolon in TProtocolUtil.h makes clang mad
- * [THRIFT-2215] - Generated HTML/Graphviz lists referenced enum identifiers as UNKNOWN.
- * [THRIFT-2211] - Exception constructor does not contain namespace prefix.
- * [THRIFT-2210] - lib/java TSimpleJSONProtocol can emit invalid JSON
- * [THRIFT-2209] - Ruby generator -- please namespace classes
- * [THRIFT-2202] - Delphi TServerImpl.DefaultLogDelegate may stop the server with I/O-Error 105
- * [THRIFT-2201] - Ternary operator returns different types (build error for some compilers)
- * [THRIFT-2200] - nested structs cause generate_fingerprint() to slow down at excessive CPU load
- * [THRIFT-2197] - fix jar output directory in rpm spec file
- * [THRIFT-2196] - Fix invalid dependency in Makefile.am
- * [THRIFT-2194] - Node: Not actually prepending residual data in TFramedTransport.receiver
- * [THRIFT-2193] - Java code generator emits spurious semicolon when deep copying binary data
- * [THRIFT-2191] - Fix charp JSONProtocol.ReadJSONDouble (specify InvariantCulture)
- * [THRIFT-2214] - System header sys/param.h is included inside the Thrift namespace
- * [THRIFT-2178] - Thrift generator returns error exit code on --version
- * [THRIFT-2171] - NodeJS implementation has extremely low test coverage
- * [THRIFT-2183] - gem install fails on zsh
- * [THRIFT-2182] - segfault in regression tests (GC bug in rb_thrift_memory_buffer_write)
- * [THRIFT-2181] - oneway calls don't work in NodeJS
- * [THRIFT-2169] - JavaME Thrift Library causes "java.io.IOException: No Response Entries Available" after using the Thrift client for some time
- * [THRIFT-2168] - Node.js appears broken (at least, examples don't work as intended)
- * [THRIFT-2293] - TSSLTransportFactory.createSSLContext() leaves files open
- * [THRIFT-2279] - TSerializer only returns the first 1024 bytes serialized
- * [THRIFT-2278] - Buffered transport doesn't support writes > buffer size
- * [THRIFT-2275] - Fix memory leak in golang compact_protocol.
- * [THRIFT-2282] - Incorect code generated for some typedefs
- * [THRIFT-2009] - Go redeclaration error
- * [THRIFT-1964] - 'Isset' causes problems with C#/.NET serializers
- * [THRIFT-2026] - Fix TCompactProtocol 64 bit builds
- * [THRIFT-2108] - Fix TAsyncClientManager timeout race
- * [THRIFT-2068] - Multiple calls from same connection are not processed in node
- * [THRIFT-1750] - Make compiler build cleanly under visual studio 10
- * [THRIFT-1755] - Comment parsing bug
- * [THRIFT-1771] - "make check" fails on x64 for libboost_unit_test_framework.a
- * [THRIFT-1841] - NodeJS Thrift incorrectly parses non-UTF8-string types
- * [THRIFT-1908] - Using php thrift_protocol accelerated transfer causes core dump
- * [THRIFT-1892] - Socket timeouts are declared in milli-seconds, but are actually set in micro-seconds
- * [THRIFT-2303] - TBufferredTransport not properly closing underlying transport
- * [THRIFT-2313] - nodejs server crash after processing the first request when using MultiplexedProcessor/FramedBuffer/BinaryProtocol
- * [THRIFT-2311] - Go: invalid code generated when exception name is a go keyword
- * [THRIFT-2308] - node: TJSONProtocol parse error when reading from buffered message
- * [THRIFT-2316] - ccp: TFileTransportTest
- * [THRIFT-2352] - msvc failed to compile thrift tests
- * [THRIFT-2337] - Golang does not report TIMED_OUT exceptions
- * [THRIFT-2340] - Generated server implementation does not send response type EXCEPTION on the Thrift.TApplicationExceptionType.UNKNOWN_METHOD exception
- * [THRIFT-2354] - Connection errors can lead to case_clause exceptions
- * [THRIFT-2339] - Uncaught exception in thrift c# driver
- * [THRIFT-2356] - c++ thrift client not working with ssl (SSL_connect hangs)
- * [THRIFT-2331] - Missing call to ReadStructBegin() in TApplicationException.Read()
- * [THRIFT-2323] - Uncompileable Delphi code generated for typedef'd structs
- * [THRIFT-2322] - Correctly show the number of times ExecutorService (java) has rejected the client.
- * [THRIFT-2389] - namespaces handled wrongly in acrionscript 3.0 implementation
- * [THRIFT-2388] - GoLang - Fix data races in simple_server and server_socket
- * [THRIFT-2386] - Thrift refuses to link yylex
- * [THRIFT-2375] - Excessive <br>'s in generated HTML
- * [THRIFT-2373] - warning CS0414 in THttpClient.cs: private field 'Thrift.Transport.THttpClient.connection' assigned but never used
- * [THRIFT-2372] - thrift/json_protocol.go:160: function ends without a return statement
- * [THRIFT-2371] - ruby bundler version fails on ~1.3.1, remove and take latest avail
- * [THRIFT-2370] - Compiler SEGFAULTs generating HTML documentation for complex strucre
- * [THRIFT-2384] - Binary map keys produce uncompilable code in go
- * [THRIFT-2380] - unreachable code (CID 1174546, CID 1174679)
- * [THRIFT-2378] - service method arguments of binary type lead to uncompileable Go code
- * [THRIFT-2363] - Issue with character encoding of Success returned from Login using Thrift Proxy and NodeJS
- * [THRIFT-2359] - TBufferedTransport doesn't clear it's buffer on a failed flush call
- * [THRIFT-2428] - Python 3 setup.py support
- * [THRIFT-2367] - Build failure: stdlib and boost both define uint64_t
- * [THRIFT-2365] - C# decodes too many binary bytes from JSON
- * [THRIFT-2402] - byte count of FrameBuffer in AWAITING_CLOSE state is not subtracted from readBufferBytesAllocated
- * [THRIFT-2396] - Build Error on MacOSX
- * [THRIFT-2395] - thrift Ruby gem requires development dependency 'thin' regardless of environment
- * [THRIFT-2414] - c_glib fix several bug.
- * [THRIFT-2420] - Go argument parser for methods without arguments does not skip fields
- * [THRIFT-2439] - Bug in TProtocolDecorator Class causes parsing errors
- * [THRIFT-2419] - golang - Fix fmt.Errorf in generated code
- * [THRIFT-2418] - Go handler function panics on internal error
- * [THRIFT-2405] - Node.js Multiplexer tests fail (silently)
- * [THRIFT-2581] - TFDTransport destructor should not throw
- * [THRIFT-2575] - Thrift includes siginfo_t within apache::thrift::protocol namespace
- * [THRIFT-2577] - TFileTransport missuse of closesocket on windows platform
- * [THRIFT-2576] - Implement Thrift.Protocol.prototype.skip method in JavaScript library
- * [THRIFT-2588] - Thrift compiler is not buildable in Visual Studio 2010
- * [THRIFT-2594] - JS Compiler: Single quotes are not being escaped in constants.
- * [THRIFT-2591] - TFramedTransport does not handle payloads split across packets correctly
- * [THRIFT-2599] - Uncompileable Delphi code due to naming conflicts with IDL
- * [THRIFT-2590] - C++ Visual Studio solution doesn't include Multiplexing support
- * [THRIFT-2595] - Node.js: Fix global leaks and copy-paste errors
- * [THRIFT-2565] - autoconf fails to find mingw-g++ cross compiler on travis CI
- * [THRIFT-2555] - excessive "unused field" comments
- * [THRIFT-2554] - double initialization in generated Read() method
- * [THRIFT-2551] - OutOfMemoryError "unable to create new native thread" kills serve thread
- * [THRIFT-2543] - Generated enum type in haskell should be qualified
- * [THRIFT-2560] - Thrift compiler generator tries to concat ints with strings using +
- * [THRIFT-2559] - Centos 6.5 unable to "make" with Thrift 0.9.1
- * [THRIFT-2526] - Assignment operators and copy constructors in c++ don't copy the __isset struct
- * [THRIFT-2454] - c_glib: There is no gethostbyname_r() in some OS.
- * [THRIFT-2451] - Do not use pointers for optional fields with defaults. Do not write such fields if its value set to default. Also, do not use pointers for any optional fields mapped to go map or slice. generate Get accessors
- * [THRIFT-2450] - include HowToContribute in the src repo
- * [THRIFT-2448] - thrift/test/test.sh has incorrect Node.js test path
- * [THRIFT-2460] - unopened socket fd must be less than zero.
- * [THRIFT-2459] - --version should not exit 1
- * [THRIFT-2468] - Timestamp handling
- * [THRIFT-2467] - Unable to build contrib/fb303 on OSX 10.9.2
- * [THRIFT-2466] - Improper error handling for SSL/TLS connections that don't complete a handshake
- * [THRIFT-2463] - test/py/RunClientServer.py fails sometimes
- * [THRIFT-2458] - Generated golang server code for "oneway" methods is incorrect
- * [THRIFT-2456] - THttpClient fails when using async support outside Silverlight
- * [THRIFT-2524] - Visual Studio project is missing TThreadedServer files
- * [THRIFT-2523] - Visual Studio project is missing OverlappedSubmissionThread files
- * [THRIFT-2520] - cpp:cob_style generates incorrect .tcc file
- * [THRIFT-2508] - Uncompileable C# code due to language keywords in IDL
- * [THRIFT-2506] - Update TProtocolException error codes to be used consistently throughout the library
- * [THRIFT-2505] - go: struct should always be a pointer to avoid copying of potentially size-unbounded structs
- * [THRIFT-2515] - TLS Method error during make
- * [THRIFT-2503] - C++: Fix name collision when a struct has a member named "val"
- * [THRIFT-2477] - thrift --help text with misplaced comma
- * [THRIFT-2492] - test/cpp does not compile on mac
- * [THRIFT-2500] - sending random data crashes thrift(golang) service
- * [THRIFT-2475] - c_glib: buffered_transport_write function return always TRUE.
- * [THRIFT-2495] - JavaScript/Node string constants lack proper escaping
- * [THRIFT-2491] - unable to import generated ThriftTest service
- * [THRIFT-2490] - c_glib: if fail to read a exception from server, client may be occurred double free
- * [THRIFT-2470] - THttpHandler swallows exceptions from processor
- * [THRIFT-2533] - Boost version in requirements should be updated
- * [THRIFT-2532] - Java version in installation requirements should be updated
- * [THRIFT-2529] - TBufferedTransport split Tcp data bug in nodeJs
- * [THRIFT-2537] - Path for "go get" does not work (pull request 115)
- * [THRIFT-2443] - Node fails cross lang tests
- * [THRIFT-2437] - Author fields in Python setup.py must be strings not lists.
- * [THRIFT-2435] - Java compiler doesn't like struct member names that are identical to an existing enum or struct type
- * [THRIFT-2434] - Missing namespace import for php TMultiplexedProcessor implementation
- * [THRIFT-2432] - Flaky parallel build
- * [THRIFT-2430] - Crash during TThreadPoolServer shutdown
- * [THRIFT-667] - Period should not be allowed in identifier names
- * [THRIFT-1212] - Members capital case conflict
- * [THRIFT-2584] - Error handler not listened on javascript client
- * [THRIFT-2294] - Incorrect Makefile generation
- * [THRIFT-2601] - Fix vagrant to work again for builds again
- * [THRIFT-2092] - TNonblocking server should release handler as soon as connection closes
- * [THRIFT-2557] - CS0542 member names cannot be the same as their enclosing type
- * [THRIFT-2605] - TSocket warning on gcc 4.8.3
- * [THRIFT-2607] - ThreadManager.cpp warning on clang++ 3.4
- * [THRIFT-1998] - TCompactProtocol.tcc - one more warning on Visual 2010
- * [THRIFT-2610] - MSVC warning in TSocket.cpp
- * [THRIFT-2614] - TNonblockingServer.cpp warnings on MSVC
- * [THRIFT-2608] - TNonblockingServer.cpp warnings on clang 3.4
- * [THRIFT-2606] - ThreadManager.h warning in clang++ 3.4
- * [THRIFT-2609] - TFileTransport.h unused field warning (clang 3.4)
- * [THRIFT-2416] - Cannot use TCompactProtocol with MSVC
- * [THRIFT-1803] - Ruby Thrift 0.9.0 tries to encode UUID to UTF8 and crashes
- * [THRIFT-2385] - Problem with gethostbyname2 during make check
- * [THRIFT-2262] - thrift server 'MutateRow' operation gives no indication of success / failure
- * [THRIFT-2048] - Prefer boolean context to nullptr_t conversion
- * [THRIFT-2528] - Thrift Erlang Library: Multiple thrift applications in one bundle
- * [THRIFT-1999] - warning on gcc 4.7 while compiling BoostMutex.cpp
- * [THRIFT-2104] - Structs lose binary data when transferred from server to client in Java
- * [THRIFT-2184] - undefined method rspec_verify for Thrift::MemoryBufferTransport
- * [THRIFT-2351] - PHP TCompactProtocol has fails to decode messages
- * [THRIFT-2016] - Resource Leak in thrift struct under compiler/cpp/src/parse/t_function.h
- * [THRIFT-2273] - Please delete old releases from mirroring system
- * [THRIFT-2270] - Faulty library version numbering at build or documentation
- * [THRIFT-2203] - Tests keeping failing on Jenkins and Travis CI
- * [THRIFT-2399] - thrift.el: recognize "//"-style comments in emacs thrift-mode
- * [THRIFT-2582] - "FileTransport error" exception is raised when trying to use Java's TFileTransport
- * [THRIFT-1682] - Multiple thread calling a Service function unsafely causes message corruption and terminates with Broken Pipe
- * [THRIFT-2357] - recurse option has no effect when generating php
- * [THRIFT-2248] - Go generator doesn't deal well with map keys of type binary
- * [THRIFT-2426] - clarify IP rights and contributions from fbthrift
- * [THRIFT-2041] - TNonblocking server compilation on windows (ARITHMETIC_RIGHT_SHIFT)
- * [THRIFT-2400] - thrift.el: recognize "//"-style comments in emacs thrift-mode
- * [THRIFT-1717] - Fix deb build in jenkins
- * [THRIFT-2266] - ThreadManager.h:24:10: fatal error: 'tr1/functional' file not found on Mac 10.9 (Mavericks)
- * [THRIFT-1300] - Test failures with parallel builds (make -j)
- * [THRIFT-2487] - Tutorial requires two IDL files but only one is linked from the Thrift web site
- * [THRIFT-2329] - missing release tags within git
- * [THRIFT-2306] - concurent client calls with nodejs
- * [THRIFT-2222] - ruby gem cannot be compiled on OS X mavericks
- * [THRIFT-2381] - code which generated by thrift2/hbase.thrift compile error
- * [THRIFT-2390] - no close event when connection lost
- * [THRIFT-2146] - Unable to pass multiple "--gen" options to the thrift compiler
- * [THRIFT-2438] - Unexpected readFieldEnd call causes JSON Parsing errors
- * [THRIFT-2498] - Error message "Invalid method name" while trying to call HBase Thrift API
- * [THRIFT-841] - Build cruft
- * [THRIFT-2570] - Wrong URL given in http://thrift.apache.org/developers
- * [THRIFT-2604] - Fix debian packaging
- * [THRIFT-2618] - Unignore /aclocal files required for build
- * [THRIFT-2562] - ./configure create MakeFile in lib/d with errors
- * [THRIFT-2593] - Unable to build thrift on ubuntu-12.04 (Precise)
- * [THRIFT-2461] - Can't install thrift-0.8.0 on OS X 10.9.2
- * [THRIFT-2602] - Fix missing dist files
- * [THRIFT-2620] - Fix python packaging
- * [THRIFT-2545] - Test CPP fails to build (possibly typo)
-
-## Documentation
- * [THRIFT-2155] - Adding one liner guide to rename the version.h.in and rename thrifty.cc.h
- * [THRIFT-1991] - Add exceptions to examples
- * [THRIFT-2334] - add a tutorial for node JS
- * [THRIFT-2392] - Actionscript tutorial
- * [THRIFT-2383] - contrib: sample for connecting Thrift with Rebus
- * [THRIFT-2382] - contrib: sample for connecting Thrift with STOMP
-
-## Improvement
- * [THRIFT-1457] - Capacity of TframedTransport write buffer is never reset
- * [THRIFT-1135] - Node.js tutorial
- * [THRIFT-1371] - Socket timeouts (SO_RCVTIMEO and SO_SNDTIMEO) not supported on Solaris
- * [THRIFT-2142] - Minor tweaks to thrift.el for better emacs package compatibility
- * [THRIFT-2268] - Modify TSaslTransport to ignore TCP health checks from loadbalancers
- * [THRIFT-2264] - GitHub page incorrectly states that Thrift is still incubating
- * [THRIFT-2263] - Always generate good hashCode for Java
- * [THRIFT-2233] - Java compiler should defensively copy its binary inputs
- * [THRIFT-2239] - Address FindBugs errors
- * [THRIFT-2249] - Add SMP Build option to thrift.spec (and three config defines)
- * [THRIFT-2254] - Exceptions generated by Go compiler should implement error interface
- * [THRIFT-2260] - Thrift imposes unneeded dependency on commons-lang3
- * [THRIFT-2258] - Add TLS v1.1/1.2 support to TSSLSocket.cpp
- * [THRIFT-2205] - Node.js Test Server to support test.js JavaScript Browser test and sundry fixes
- * [THRIFT-2204] - SSL client for the cocoa client
- * [THRIFT-2172] - Java compiler allocates optionals array for every struct with an optional field
- * [THRIFT-2185] - use cabal instead of runhaskell in haskell library
- * [THRIFT-1926] - PHP Constant Generation Refactoring
- * [THRIFT-2029] - Port C++ tests to Windows
- * [THRIFT-2054] - TSimpleFileTransport - Java Lib has no straight forward TTransport based file transport
- * [THRIFT-2040] - "uninitialized variable" warnings on MSVC/windows
- * [THRIFT-2034] - Give developers' C++ code direct access to socket FDs on server side
- * [THRIFT-2095] - Use print function for Python 3 compatiblity
- * [THRIFT-1868] - Make the TPC backlog configurable in the Java servers
- * [THRIFT-1813] - Add @Generated annotation to generated classes
- * [THRIFT-1815] - Code generators line buffer output
- * [THRIFT-2305] - TFramedTransport empty constructor should probably be private
- * [THRIFT-2304] - Move client assignments from construtor in method
- * [THRIFT-2309] - Ruby (gem) & PHP RPM subpackages
- * [THRIFT-2318] - perl: dependency Class::Accessor not checked
- * [THRIFT-2317] - exclude tutorial from build
- * [THRIFT-2320] - Program level doctext does not get attached by parser
- * [THRIFT-2349] - Golang - improve tutorial
- * [THRIFT-2348] - PHP Generator: add array typehint to functions
- * [THRIFT-2344] - configure.ac: compiler-only option
- * [THRIFT-2343] - Golang - Return a single error for all exceptions instead of multiple return values
- * [THRIFT-2341] - Enable generation of Delphi XMLDoc comments (a.k.a. "Help Insight")
- * [THRIFT-2355] - Add SSL and Web Socket Support to Node and JavaScript
- * [THRIFT-2350] - Add async calls to normal JavaScript
- * [THRIFT-2330] - Generate PHPDoc comments
- * [THRIFT-2332] - RPMBUILD: run bootstrap (if needed)
- * [THRIFT-2391] - simple socket transport for actionscript 3.0
- * [THRIFT-2376] - nodejs: allow Promise style calls for client and server
- * [THRIFT-2369] - Add ssl support for nodejs implementation
- * [THRIFT-2401] - Haskell tutorial compiles
- * [THRIFT-2417] - C# Union classes are not partial
- * [THRIFT-2415] - Named pipes server performance & message mode
- * [THRIFT-2404] - emit warning on (typically inefficient) list<byte>
- * [THRIFT-2398] - Improve Node Server Library
- * [THRIFT-2397] - Add CORS and CSP support for JavaScript and Node.js libraries
- * [THRIFT-2407] - use markdown (rename README => README.md)
- * [THRIFT-2300] - D configure info output should follow same format as other languages
- * [THRIFT-2579] - Windows CE support
- * [THRIFT-2574] - Compiler option to generate namespace directories for Ruby
- * [THRIFT-2571] - Simplify cross compilation using CMake
- * [THRIFT-2569] - Introduce file to specify third party library locations on Windows
- * [THRIFT-2568] - Implement own certificate handler
- * [THRIFT-2552] - eliminate warning from configure.ac
- * [THRIFT-2549] - Generate json tag for struct members. use go.tag annotation to override the default generated tag.
- * [THRIFT-2544] - Add support for socket transport for c# library when using Windows Phone projects
- * [THRIFT-2453] - haskell tutorial: fix up division by 0 example
- * [THRIFT-2449] - Enhance typedef structure to distinguish between forwards and real typedefs
- * [THRIFT-2446] - There is no way to handle server stream errors
- * [THRIFT-2455] - Allow client certificates to be used with THttpClient
- * [THRIFT-2511] - Node.js needs the compact protocol
- * [THRIFT-2493] - Node.js lib needs HTTP client
- * [THRIFT-2502] - Optimize go implementations of binary and compact protocols for speed
- * [THRIFT-2494] - Add enum toString helper function in c_glib
- * [THRIFT-2471] - Make cpp.ref annotation language agnostic
- * [THRIFT-2497] - server and client for test/go, also several fixes and improvements
- * [THRIFT-2535] - TJSONProtocol when serialized yields TField ids rather than names
- * [THRIFT-2220] - Add a new struct structv?
- * [THRIFT-1352] - Thrift server
- * [THRIFT-989] - Push boost m4 macros upstream
- * [THRIFT-1349] - Remove unnecessary print outs
- * [THRIFT-2496] - server and client for test/go, also several fixes and improvements
- * [THRIFT-1114] - Maven publish shouldn't require passwords hardcoded in settings.xml
- * [THRIFT-2043] - visual 2010 warnings - unreachable code
- * [THRIFT-1683] - Implement alternatives to Javascript Client side Transport protocol, just as NPAPI and WebSocket.
- * [THRIFT-1746] - provide a SPDX file
- * [THRIFT-1772] - Serialization does not check types of embedded structures.
- * [THRIFT-2387] - nodejs: external imports should be centralized in index.js
- * [THRIFT-2037] - More general macro THRIFT_UNUSED_VARIABLE
-
-## New Feature
- * [THRIFT-1012] - Transport for DataInput DataOutput interface
- * [THRIFT-2256] - Using c++11/c++0x std library replace boost library
- * [THRIFT-2250] - JSON and MemoryBuffer for JavaME
- * [THRIFT-2114] - Python Service Remote SSL Option
- * [THRIFT-1719] - SASL client support for Python
- * [THRIFT-1894] - Thrift multi-threaded async Java Server using Java 7 AsynchronousChannelGroup
- * [THRIFT-1893] - HTTP/JSON server/client for node js
- * [THRIFT-2347] - C# TLS Transport based on THRIFT-181
- * [THRIFT-2377] - Allow addition of custom HTTP Headers to an HTTP Transport
- * [THRIFT-2408] - Named Pipe Transport Option for C#
- * [THRIFT-2572] - Add string/collection length limit checks (from C++) to java protocol readers
- * [THRIFT-2469] - "java:fullcamel" option to automatically camel-case underscored attribute names
- * [THRIFT-795] - Importing service functions (simulation multiple inheritance)
- * [THRIFT-2164] - Add a Get/Post Http Server to Node along with examples
- * [THRIFT-2255] - add Parent Class for generated Struct class
-
-## Question
- * [THRIFT-2539] - Tsocket.cpp addrinfo ai_flags = AI_ADDRCONFIG
- * [THRIFT-2440] - how to connect as3 to java by thrift ,
- * [THRIFT-2379] - Memmory leaking while using multithreading in C++ server.
- * [THRIFT-2277] - Thrift: installing fb303 error
- * [THRIFT-2567] - Csharp slow ?
- * [THRIFT-2573] - thrift 0.9.2 release
-
-## Sub-task
- * [THRIFT-981] - cocoa: add version Info to the library
- * [THRIFT-2132] - Go: Support for Multiplexing Services on any Transport, Protocol and Server
- * [THRIFT-2299] - TJsonProtocol implementation for Ruby does not allow for both possible slash (solidus) encodings
- * [THRIFT-2298] - TJsonProtocol implementation for C# does not allow for both possible slash (solidus) encodings
- * [THRIFT-2297] - TJsonProtocol implementation for Delphi does not allow for both possible slash (solidus) encodings
- * [THRIFT-2271] - JavaScript: Support for Multiplexing Services
- * [THRIFT-2251] - go test for compact protocol is not running
- * [THRIFT-2195] - Delphi: Add event handlers for server and processing events
- * [THRIFT-2176] - TSimpleJSONProtocol.ReadFieldBegin() does not return field type and ID
- * [THRIFT-2175] - Wrong field type set for binary
- * [THRIFT-2174] - Deserializing JSON fails in specific cases
- * [THRIFT-2053] - NodeJS: Support for Multiplexing Services
- * [THRIFT-1914] - Python: Support for Multiplexing Services on any Transport, Protocol and Server
- * [THRIFT-1810] - add ruby to test/test.sh
- * [THRIFT-2310] - PHP: Client-side support for Multiplexing Services
- * [THRIFT-2346] - C#: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
- * [THRIFT-2345] - Delphi: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
- * [THRIFT-2338] - First doctext wrongly interpreted as program doctext in some cases
- * [THRIFT-2325] - SSL test certificates
- * [THRIFT-2358] - C++: add compact protocol to cross language test suite
- * [THRIFT-2425] - PHP: Server-side support for Multiplexing Services
- * [THRIFT-2421] - Tree/Recursive struct support in thrift
- * [THRIFT-2290] - Update Go tutorial to align with THRIFT-2232
- * [THRIFT-2558] - CSharp compiler generator tries to concat ints with strings using +
- * [THRIFT-2507] - Additional LUA TProtocolException error code needed?
- * [THRIFT-2499] - Compiler: allow annotations without "= value"
- * [THRIFT-2534] - Cross language test results should recorded to a status.md or status.html file automatically
- * [THRIFT-66] - Java: Allow multiplexing multiple services over a single TCP connection
- * [THRIFT-1681] - Add Lua Support
- * [THRIFT-1727] - Ruby-1.9: data loss: "binary" fields are re-encoded
- * [THRIFT-1726] - Ruby-1.9: "binary" fields are represented by string whose encoding is "UTF-8"
- * [THRIFT-988] - perl: add version Info to the library via configure
- * [THRIFT-334] - Compact Protocol for PHP
- * [THRIFT-2444] - pull request 88: thrift: clean up enum value assignment
-
-## Task
- * [THRIFT-2223] - Spam links on wiki
- * [THRIFT-2566] - Please create a DOAP file for your TLP
- * [THRIFT-2237] - Update archive to contain all versions
- * [THRIFT-962] - Tutorial page on our website is really unhelpful
-
-## Test
- * [THRIFT-2327] - nodejs: nodejs test suite should be bundled with the library
- * [THRIFT-2445] - THRIFT-2384 (code generation for go maps with binary keys) should be tested
- * [THRIFT-2501] - C# The test parameters from the TestServer and TestClient are different from the http://thrift.apache.org/test/
-
-## Wish
- * [THRIFT-2190] - Add the JavaScript thrift.js lib to the Bower registry
- * [THRIFT-2076] - boost::optional instead of __isset
-
-
-
-Thrift 0.9.1
---------------------------------------------------------------------------------
-## Bug
- * [THRIFT-1440] - debian packaging: minor-ish policy problems
- * [THRIFT-1402] - Generated Y_types.js does not require() X_types.js when an include in the IDL file was used
- * [THRIFT-1551] - 2 thrift file define only struct (no service), one include another, the gen nodejs file didn't have "requires" at the top
- * [THRIFT-1264] - TSocketClient is queried by run loop after deallocation in Cocoa
- * [THRIFT-1600] - Thrift Go Compiler and Library out of date with Go 1 Release.
- * [THRIFT-1603] - Thrift IDL allows for multiple exceptions, args or struct member names to be the same
- * [THRIFT-1062] - Problems with python tutorials
- * [THRIFT-864] - default value fails if identifier is a struct
- * [THRIFT-930] - Ruby and Haskell bindings don't properly support DESTDIR (makes packaging painful)
- * [THRIFT-820] - The readLength attribute of TBinaryProtocol is used as an instance variable and is decremented on each call of checkReadLength
- * [THRIFT-1640] - None of the tutorials linked on the website contain content
- * [THRIFT-1637] - NPM registry does not include version 0.8
- * [THRIFT-1648] - NodeJS clients always receive 0 for 'double' values.
- * [THRIFT-1660] - Python Thrift library can be installed with pip but not easy_install
- * [THRIFT-1657] - Chrome browser sending OPTIONS method before POST in xmlHttpRequest
- * [THRIFT-2118] - Certificate error handling still incorrect
- * [THRIFT-2137] - Ruby test lib fails jenkins build #864
- * [THRIFT-2136] - Vagrant build not compiling java, ruby, php, go libs due to missing dependencies
- * [THRIFT-2135] - GO lib leaves behind test files that are auto generated
- * [THRIFT-2134] - mingw-cross-compile script failing with strip errors
- * [THRIFT-2133] - java TestTBinaryProtocol.java test failing
- * [THRIFT-2126] - lib/cpp/src/thrift/concurrency/STD* files missing from DIST
- * [THRIFT-2125] - debian missing from DIST
- * [THRIFT-2124] - .o, .so, .la, .deps, .libs, gen-* files left tutorials, test and lib/cpp when making DIST
- * [THRIFT-2123] - GO lib missing files in DIST build
- * [THRIFT-2121] - Compilation bug for Node.js
- * [THRIFT-2129] - php ext missing from dist
- * [THRIFT-2128] - lib GO tests fail with funct ends without a return statement
- * [THRIFT-2286] - Failed to compile Thrift0.9.1 with boost1.55 by VS2010 if select Debug-mt&x64 mode.
- * [THRIFT-1973] - TCompactProtocol in C# lib does not serialize and deserialize negative int32 and int64 number correctly
- * [THRIFT-1992] - casts in TCompactProtocol.tcc causing "dereferencing type-punned pointer will break strict-aliasing rules" warnings from gcc
- * [THRIFT-1930] - C# generates unsigned byte for Thrift "byte" type
- * [THRIFT-1929] - Update website to use Mirrors for downloads
- * [THRIFT-1928] - Race may still exist in TFileTransport::flush()
- * [THRIFT-1934] - Tabs in Example section on main page are not working
- * [THRIFT-1933] - Delphi generator crashes when a typedef references another typedef from an included file
- * [THRIFT-1942] - Binary accelerated cpp extension does not use Thrift namespaces for Exceptions
- * [THRIFT-1959] - C#: Add Union TMemoryBuffer support
- * [THRIFT-1958] - C#: Use static Object.Equals instead of .Equals() calls in equals
- * [THRIFT-1957] - NodeJS TFramedTransport and TBufferedTransport read bytes as unsigned
- * [THRIFT-1955] - Union Type writer generated in C# does not WriteStructBegin
- * [THRIFT-1952] - Travis CI
- * [THRIFT-1949] - WP7 build broken
- * [THRIFT-1943] - docstrings for enum values are ignored
- * [THRIFT-2070] - Improper `HexChar' and 'HexVal' implementation in TJSONProtocol.cs
- * [THRIFT-2017] - Resource Leak in thrift struct under compiler/cpp/src/parse/t_program.h
- * [THRIFT-2032] - C# client leaks sockets/handles
- * [THRIFT-1996] - JavaME Constants generation is broken / inconsistent with regular Java generation
- * [THRIFT-2002] - Haskell: Test use Data.Maybe instead of Maybe
- * [THRIFT-2051] - Vagrant fails to build erlang
- * [THRIFT-2050] - Vagrant C# lib compile fails with TException missing
- * [THRIFT-1978] - Ruby: Thrift should allow for the SSL verify mode to be set
- * [THRIFT-1984] - namespace collision in python bindings
- * [THRIFT-1988] - When trying to build a debian package it fails as the file NEWS doesn't exist
- * [THRIFT-1975] - TBinaryProtocol CheckLength can't be used for a client
- * [THRIFT-1995] - '.' allowed at end of identifier generates non-compilable code
- * [THRIFT-2112] - Error in Go generator when using typedefs in map keys
- * [THRIFT-2088] - Typos in Thrift compiler help text
- * [THRIFT-2080] - C# multiplex processor does not catch IOException
- * [THRIFT-2082] - Executing "gmake clean" is broken
- * [THRIFT-2102] - constants are not referencing to correct type when included from another thrift file
- * [THRIFT-2100] - typedefs are not correctly referenced when including from other thrift files
- * [THRIFT-2066] - 'make install' does not install two headers required for C++ bindings
- * [THRIFT-2065] - Not valid constants filename in Java
- * [THRIFT-2047] - Thrift.Protocol.TCompactProtocol, intToZigZag data lost (TCompactProtocol.cs)
- * [THRIFT-2036] - Thrift gem warns about class variable access from top level
- * [THRIFT-2057] - Vagrant fails on php tests
- * [THRIFT-2105] - Generated code for default values of collections ignores t_field::T_REQUIRED
- * [THRIFT-2091] - Unnecessary 'friend' declaration causes warning in TWinsockSingleton
- * [THRIFT-2090] - Go generator, fix including of other thrift files
- * [THRIFT-2106] - Fix support for namespaces in GO generator
- * [THRIFT-1783] - C# doesn't handle required fields correctly
- * [THRIFT-1782] - async only defined in silverlight
- * [THRIFT-1779] - Missing process_XXXX method in generated TProcessor implementation for all 'oneway' service functions
- * [THRIFT-1692] - SO_REUSEADDR allows for socket hijacking on Windows
- * [THRIFT-1720] - JRuby times out on successful connection
- * [THRIFT-1713] - Named and Anonymous Pipe transport (Delphi)
- * [THRIFT-1699] - Native Union#read has extra read_field_end call
- * [THRIFT-1749] - Python TSSLSocket error handling obscures actual error
- * [THRIFT-1748] - Guard and RWGuard macros defined in global namespace
- * [THRIFT-1734] - Front webpage is still advertising v0.8 as current release
- * [THRIFT-1729] - C glib refactor left empty folders in svn
- * [THRIFT-1767] - unions can't have required fields (Delphi)
- * [THRIFT-1765] - Incorrect error message printed for null or negative keys
- * [THRIFT-1778] - Configure requires manual intervention due to tar failure
- * [THRIFT-1777] - TPipeServer is UNSTOPPABLE
- * [THRIFT-1753] - Multiple C++ Windows, OSX, and iOS portability issues
- * [THRIFT-1756] - 'make -j 8' fails with "unterminated #ifdef" error
- * [THRIFT-1773] - Python library should run on python 2.4
- * [THRIFT-1769] - unions can't have required fields (C++)
- * [THRIFT-1768] - unions can't have required fields (Compiler)
- * [THRIFT-1666] - htonll usage in TBinaryProtocol.tcc generates warning with MSVC2010
- * [THRIFT-1919] - libthrift depends on httpcore-4.1.3 (directly) and httpcore-4.1.4 (transitively)
- * [THRIFT-1864] - implement event handler for non-blocking server
- * [THRIFT-1859] - Generated error c++ code with -out and include_prefix param
- * [THRIFT-1869] - TThreadPoolServer (java) dies when threadpool is consumed
- * [THRIFT-1842] - Memory leak with Pipes
- * [THRIFT-1838] - Can't build compiler on OS X because of missing thrifty.h
- * [THRIFT-1846] - Restore socket.h header to support builds with Android NDK
- * [THRIFT-1850] - make check hangs on TSocket tests in TransportTest.cpp
- * [THRIFT-1873] - Binary protocol factory ignores struct read/write flags
- * [THRIFT-1872] - issues with TBufferedTransport buffer
- * [THRIFT-1904] - Incorrect code is generated for typedefs which use included types
- * [THRIFT-1903] - PHP namespaces cause binary protocols to not be used
- * [THRIFT-1895] - Delphi: reserved variable name "result" not detected properly
- * [THRIFT-1881] - TNonblockingServer does not release open connections or threads on shutdown
- * [THRIFT-1888] - Java Thrift client can't connect to Python Thrift server on same host
- * [THRIFT-1831] - Bug in list deserializer
- * [THRIFT-1824] - many compile warning, becase Thread.h includes config.h
- * [THRIFT-1823] - Missing parenthesis breaks "IS_..." macro in generated code
- * [THRIFT-1806] - Python generation always truncates __init__.py files
- * [THRIFT-1795] - Race condition in TThreadedServerPool java implementation
- * [THRIFT-1794] - C# asyncctp broken
- * [THRIFT-1804] - Binary+compact protocol single byte error in Ruby library (ARM architecture): caused by different char signedness
- * [THRIFT-1800] - Documentation text not always escaped correctly when rendered to HTML
- * [THRIFT-1788] - C#: Constants static constructor does not compile
- * [THRIFT-1816] - Need "require" included thrift files in "xxx_types.js"
- * [THRIFT-1907] - Compiling namespace and sub-namespace directives for unrecognized generators should only be a warning
- * [THRIFT-1913] - skipping unknown fields in java unions
- * [THRIFT-2553] - C++ linker error - transport/TSocket
- * [THRIFT-274] - Towards a working release/versioning process
-
-## Documentation
- * [THRIFT-1971] - [Graphviz] Adds tutorial/general description documentation
- * [THRIFT-2001] - http://thrift.apache.org/ Example "C++ Server" tab is broken
-
-## Improvement
- * [THRIFT-1574] - Apache project branding requirements: DOAP file [PATCH]
- * [THRIFT-1347] - Unify the exceptions returned in generated Go code
- * [THRIFT-1353] - Switch to performance branch, get rid of BinaryParser
- * [THRIFT-1629] - Ruby 1.9 Compatibility during Thrift configure, make, install
- * [THRIFT-991] - Refactor Haskell code and generator
- * [THRIFT-990] - Sanify gettimeofday usage codebase-wide
- * [THRIFT-791] - Let C++ TSimpleServer be driven by an external main loop
- * [THRIFT-2117] - Cocoa TBinaryProtocol strictWrite should be set to true by default
- * [THRIFT-2014] - Change C++ lib includes to use <namespace/> style throughout
- * [THRIFT-1972] - Add support for async processors
- * [THRIFT-1970] - [Graphviz] Adds option to render exceptions relationships
- * [THRIFT-1966] - Support different files for SSL certificates and keys
- * [THRIFT-1965] - Adds Graphviz (graph description language) generator
- * [THRIFT-1956] - Switch to Apache Commons Lang 3
- * [THRIFT-1962] - Multiplex processor should send any TApplicationException back to client
- * [THRIFT-1960] - main() declares 22 unused gen bools
- * [THRIFT-1951] - libthrift.jar has source files in it
- * [THRIFT-1997] - Add accept backlog configuration method to TServerSocket
- * [THRIFT-2003] - Deprecate senum
- * [THRIFT-2052] - Vagrant machine image defaults to only 384MB of RAM
- * [THRIFT-1980] - Modernize Go tooling, fix go client libary.
- * [THRIFT-1977] - C# compiler should generate constant files prefixed with thrift file name
- * [THRIFT-1985] - add a Vagrantfile to build and test Apache Thrift fully reproducable
- * [THRIFT-1994] - Deprecate slist
- * [THRIFT-1993] - Factory to create instances from known (generated) interface types with Delphi
- * [THRIFT-2081] - Specified timeout should be used in TSocket.Open()
- * [THRIFT-2084] - Delphi: Ability to create entity Thrift-generated instances based on TypeInfo
- * [THRIFT-2083] - Improve the go lib: buffered Transport, save memory allocation, handle concurrent request
- * [THRIFT-2109] - Secure connections should be supported in Go
- * [THRIFT-2107] - minor Go generator fixes
- * [THRIFT-1695] - allow warning-free compilation in VS 2012 and GNU 4.6
- * [THRIFT-1735] - integrate tutorial into regular build
- * [THRIFT-1716] - max allowed connections should be PIPE_UNLIMITED_INSTANCES
- * [THRIFT-1715] - Allow excluding python parts when building contrib/fb303
- * [THRIFT-1733] - Fix RPM build issues on RHEL6/OL6 systems
- * [THRIFT-1728] - Upgradation of httpcomponents
- * [THRIFT-1876] - Use enum names instead of casted integers in assignments
- * [THRIFT-1874] - timeout for the server-side end of a named pipe
- * [THRIFT-1897] - Support validation of required fields
- * [THRIFT-1896] - Add TBase protocol for Cocoa
- * [THRIFT-1880] - Make named pipes server work asynchronously (overlapped) to allow for clean server stops
- * [THRIFT-1878] - Add the possibility to send custom headers
- * [THRIFT-1882] - Use single include
- * [THRIFT-1793] - C#: Use static read instead of instance read
- * [THRIFT-1799] - Option to generate HTML in "standalone mode"
- * [THRIFT-1815] - Code generators line buffer output
- * [THRIFT-1890] - C++: Make named pipes server work asynchronously
- * [THRIFT-474] - Generating Ruby on Rails friendly code
-
-## New Feature
- * [THRIFT-801] - Provide an interactive shell (irb) when generating ruby bindings
- * [THRIFT-2292] - Android Library Project
- * [THRIFT-2012] - Modernizing Go
- * [THRIFT-1969] - C#: Tests not properly linked from the solution
- * [THRIFT-1785] - C#: Add TMemoryBuffer serializer/deserializer
- * [THRIFT-1780] - Add option to generate nullable values
- * [THRIFT-1786] - C# Union Typing
- * [THRIFT-591] - Make the C++ runtime library be compatible with Windows and Visual Studio
- * [THRIFT-514] - Add option to configure compiler output directory
-
-## Question
- * [THRIFT-1764] - how to get the context of client when on a rpc call in server side?
- * [THRIFT-1791] - thrift's namespace directive when generating haskell code
-
-## Sub-task
- * [THRIFT-1594] - Java test clients should have a return codes that reflect whether it succeeds or not.
- * [THRIFT-1595] - Java test server should follow the documented behavior as of THRIFT-1590
- * [THRIFT-986] - st: add version Info to the library
- * [THRIFT-985] - php: add version Info to the library
- * [THRIFT-984] - ocaml: add version Info to the library
- * [THRIFT-1924] - Delphi: Inconsistency in serialization of optional fields
- * [THRIFT-1922] - C#: Inconsistency in serialization of optional fields
- * [THRIFT-1961] - C# tests should be in lib/csharp/test/...
- * [THRIFT-1822] - PHP unit test does not work
- * [THRIFT-1902] - C++: Support for Multiplexing Services on any Transport, Protocol and Server
- * [THRIFT-1901] - C#: Support for Multiplexing Services on any Transport, Protocol and Server
- * [THRIFT-1899] - Delphi: Support for Multiplexing Services on any Transport, Protocol and Server
- * [THRIFT-563] - Support for Multiplexing Services on any Transport, Protocol and Server
-
-
-
-Thrift 0.9
---------------------------------------------------------------------------------
-## Bug
- * [THRIFT-1438] - lib/cpp/src/windows/config.h should read version from configure.ac rather than a #define
- * [THRIFT-1446] - Compile error with Delphi 2009 in constant initializer
- * [THRIFT-1450] - Problems building thrift 0.8.0 for Python and Ruby
- * [THRIFT-1449] - Ruby client does not work on solaris (?)
- * [THRIFT-1447] - NullpointerException in ProcessFunction.class :in "oneway" method
- * [THRIFT-1433] - TServerSocket fix for MSVC
- * [THRIFT-1429] - The nonblocking servers is supposed to use TransportFactory to read the data
- * [THRIFT-1427] - PHP library uses non-multibyte safe functions with mbstring function overloading
- * [THRIFT-1421] - Debian Packages can not be built
- * [THRIFT-1394] - Treatment of optional fields is not consistent between C++ and Java
- * [THRIFT-1511] - Server with oneway support ( JAVA )
- * [THRIFT-1496] - PHP compiler not namespacing enums
- * [THRIFT-1495] - PHP TestClient fatals on missing class
- * [THRIFT-1508] - TServerSocket does not allow for the user to specify the IP address to bind to
- * [THRIFT-1504] - Cocoa Generator should use local file imports for base Thrift headers
- * [THRIFT-1512] - Thrift socket support for Windows XP
- * [THRIFT-1502] - TSimpleServer::serve(): Do not print out error message if server was stopped.
- * [THRIFT-1501] - PHP old namespaces not generated for enums
- * [THRIFT-1483] - java compiler does not generate type parameters for services in extended clauses
- * [THRIFT-1479] - Compiled PHP process functions missing writeMessageEnd()
- * [THRIFT-1492] - enabling c_glib render thrift unusable (even for C++ code)
- * [THRIFT-1491] - Uninitialize processorFactory_ member in TServer.h
- * [THRIFT-1475] - Incomplete records generation for Erlang
- * [THRIFT-1486] - Javascript manual testserver not returning content types
- * [THRIFT-1488] - src/concurrency/Thread.h:91:58: error: invalid conversion from 'pthread_t {aka _opaque_pthread_t*}' to 'apache::thrift::concurrency::Thread::id_t {aka long long unsigned int}' [-fpermissive]
- * [THRIFT-1490] - Windows-specific header files - fixes & tweaks
- * [THRIFT-1526] - Union TupleSchemeFactory returns StandardSchemes
- * [THRIFT-1527] - Generated implementation of tupleReadStruct in unions return null when the setfield is unrecognized
- * [THRIFT-1524] - TNonBlockingServer does not compile in Visual Studio 2010
- * [THRIFT-1529] - TupleProtocol can unintentionally include an extra byte in bit vectors when number of optional fields is an integral of 8
- * [THRIFT-1473] - JSON context stack may be left in an incorrect state when an exception is thrown during read or write operations
- * [THRIFT-1456] - System.Net.HttpWebRequest' does not contain a definition for 'Proxy'
- * [THRIFT-1468] - Memory leak in TSaslServerTransport
- * [THRIFT-1461] - Recent TNonblockingServer changes broke --enable-boostthreads=yes, Windows
- * [THRIFT-1460] - why not add unicode strings support to python directly?
- * [THRIFT-1464] - AbstractNonblockingServer.FrameBuffer TNonblockingTransport accessor changed from public to private
- * [THRIFT-1467] - Possible AV with empty strings when using JSON protocol
- * [THRIFT-1523] - clientTimeout not worked as expected in TServerSocket created by TSSLTransportFactory
- * [THRIFT-1537] - TFramedTransport issues
- * [THRIFT-1519] - Thirft Build Failure referencing rb_intern2 symbol
- * [THRIFT-1518] - Generated C++ code only sends the first optional field in the write() function for a struct.
- * [THRIFT-1515] - NameError: global name 'TApplicationException' is not defined
- * [THRIFT-1554] - Inherited service methods are not resolved in derived service implementations
- * [THRIFT-1553] - thrift nodejs service side can't read map structure, key as enum, value as Object
- * [THRIFT-1575] - Typo in server/TThreadPoolServer.h
- * [THRIFT-1327] - Fix Spec Suite under Ruby-1.8.7 (works for MRI Ruby-1.9.2)
- * [THRIFT-1326] - on some platforms, #include <stdint.h> is necessary to be included in Thrift.h
- * [THRIFT-1159] - THttpClient->Flush() issue (connection thru proxy)
- * [THRIFT-1277] - Node.js serializes false booleans as null
- * [THRIFT-1224] - Cannot insert UTF-8 text
- * [THRIFT-1267] - Node.js can't throw exceptions.
- * [THRIFT-1338] - Do not use an unpatched autoconf 2.65 to generate release tarball
- * [THRIFT-1128] - MAC OS X: thrift.h incompatibility with Thrift.h
- * [THRIFT-1631] - Fix C++ server constructor typos
- * [THRIFT-1602] - PHP C Extension is not Compatible with PHP 5.4
- * [THRIFT-1610] - IWebProxy not available on WP7 platform
- * [THRIFT-1606] - Race condition in BoostThreadFactory.cpp
- * [THRIFT-1604] - Python exception handeling for changes from PEP 3110
- * [THRIFT-1607] - Incorrect file modes for several source files
- * [THRIFT-1583] - c_glib leaks memory
- * [THRIFT-1582] - Bad includes of nested thrift files in c_glib
- * [THRIFT-1578] - C_GLib generated code does not compile
- * [THRIFT-1597] - TJSONProtocol.php is missing from Makefile.am
- * [THRIFT-1591] - Enable TCP_NODELAY for ruby gem
- * [THRIFT-1624] - Isset Generated differently on different platforms
- * [THRIFT-1622] - Incorrect size returned on read
- * [THRIFT-1621] - Memory leaks
- * [THRIFT-1612] - Base64 encoding is broken
- * [THRIFT-1627] - compiler built using compilers.vcxproj cannot be used to build some test .thrift files
- * [THRIFT-1571] - Update Ruby HTTP transport for recent Ruby versions
- * [THRIFT-1023] - Thrift encoding (UTF-8) issue with Ruby 1.9.2
- * [THRIFT-1090] - Document the generation of a file called "Constants.java"
- * [THRIFT-1082] - Thrift::FramedTransport sometimes calls close() on an undefined value
- * [THRIFT-956] - Python module's version meta-data should be updated
- * [THRIFT-973] - Cocoa library won't compile using clang
- * [THRIFT-1632] - ruby: data corruption in thrift_native implementation of MemoryBufferTransport
- * [THRIFT-1665] - TBinaryProtocol: exceeded message length raises generic TException
- * [THRIFT-1664] - Reference to non-existing variable in build script
- * [THRIFT-1663] - Java Thrift server is not throwing exceptions
- * [THRIFT-1662] - "removeObject:" should be "removeObserver:" in [-TSocketServer dealloc]?
- * [THRIFT-1643] - Denial of Service attack in TBinaryProtocol.readString
- * [THRIFT-1674] - Update Thrift D library to be compatible with 2.060
- * [THRIFT-1673] - Ruby compile flags for extension for multi arch builds (os x)
- * [THRIFT-1655] - Configure still trying to use thrift_generators in output
- * [THRIFT-1654] - c_glib thrift_socket_read() returns corrupted data
- * [THRIFT-1653] - TThreadedSelectorServer leaks CLOSE_WAIT sockets
- * [THRIFT-1658] - Java thrift server is not throwing TApplicationException
- * [THRIFT-1656] - Setting proper headers in THttpServer.cpp so that "Cross-Origin Resource Sharing" on js client can work.
- * [THRIFT-1652] - TSaslTransport does not log the error when kerberos auth fails
- * [THRIFT-2272] - CLONE - Denial of Service attack in TBinaryProtocol.readString
- * [THRIFT-2086] - Invalid generated code for Node.JS when using namespaces
- * [THRIFT-1686] - t_php_generator.cc uses "and" instead of "&&", and causes compiler errors with Visual Studio
- * [THRIFT-1693] - libthrift has dependency on two different versions of httpcore
- * [THRIFT-1689] - don't exit(-1) in TNonblockingServer
- * [THRIFT-1679] - NodeJS: protocol readString() should treat string as utf8, not binary
- * [THRIFT-1721] - Dist broken due to 0.8.0 to 0.9.0 changes
- * [THRIFT-1710] - Minor issues in test case code
- * [THRIFT-1709] - Warning "Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first" in TBinaryProtocol.cs at ReadInt64()
- * [THRIFT-1707] - [ruby] Adjust server_spec.rb for RSpec 2.11.x and Ruby 1.9.3
- * [THRIFT-1671] - Cocoa code generator does not put keywords into generated method calls
- * [THRIFT-1670] - Incompatibilities between different versions of a Thrift interface
- * [THRIFT-1669] - NameError: global name 'TApplicationException' is not defined
- * [THRIFT-1668] - Compile error in contrib/fb303, thrift/TDispatchProcessor.h: No such file or directory
- * [THRIFT-1845] - Fix compiler warning caused by implicit string conversion with Xcode 4.6
- * [THRIFT-304] - Building the Python library requires development headers
- * [THRIFT-369] - sets and maps break equality
- * [THRIFT-556] - Ruby compiler does not correctly referred to top-level modules when a submodule masks the top-level name
- * [THRIFT-481] - indentation of ruby classes is off by a few
-
-## Improvement
- * [THRIFT-1498] - Allow TThreadedPoolServer.Args to pass a ExecutorService
- * [THRIFT-1444] - FunctionRunner - add syntactic sugar to create shared_ptrs
- * [THRIFT-1443] - define a TProcessor helper class to implement process()
- * [THRIFT-1441] - Generate constructor with parameters for exception class to let it update message property automatically.
- * [THRIFT-1520] - Embed version number in erlang .app file
- * [THRIFT-1480] - python: remove tabs, adjust whitespace and address PEP8 warnings
- * [THRIFT-1485] - Performance: pass large and/or refcounted arguments as "const"
- * [THRIFT-1484] - Introduce phpunit test suite
- * [THRIFT-1532] - The type specifications in the generated Erlang code should include "undefined" where it's used as a default value
- * [THRIFT-1534] - Required fields in the Delphi code generator.
- * [THRIFT-1469] - Java isset space optimization
- * [THRIFT-1465] - Visibility of methods in generated java code
- * [THRIFT-1453] - Don't change types of arguments when serializing with thrift php extension
- * [THRIFT-1452] - generate a swap() method for all generated structs
- * [THRIFT-1451] - FramedTransport: Prevent infinite loop when writing
- * [THRIFT-1521] - Two patches for more Performance
- * [THRIFT-1555] - Delphi version of the tutorial code
- * [THRIFT-1535] - Why thrift don't use wrapped class for optional fields ?
- * [THRIFT-1204] - Ruby autogenerated files should require 'thrift' gem
- * [THRIFT-1344] - Using the httpc module directly rather than the deprecated http layer
- * [THRIFT-1343] - no_auto_import min/2 to avoid compile warning
- * [THRIFT-1340] - Add support of ARC to Objective-C
- * [THRIFT-1611] - Improved code generation for typedefs
- * [THRIFT-1593] - Pass on errors like "connection closed" to the handler module
- * [THRIFT-1615] - PHP Namespace
- * [THRIFT-1567] - Thrift/cpp: Allow alternate classes to be used for
- * [THRIFT-1072] - Missing - (id) initWithSharedProcessor in TSharedProcessorFactory.h
- * [THRIFT-1650] - [ruby] Update clean items and svn:ignore entries for OS X artifacts
- * [THRIFT-1661] - [PATCH] Add --with-qt4 configure option
- * [THRIFT-1675] - Do we have any plan to support scala?
- * [THRIFT-1645] - Replace Object#tee with more conventional Object#tap in specs
- * [THRIFT-1644] - Upgrade RSpec to 2.10.x and refactor specs as needed
- * [THRIFT-1672] - MonoTouch (and Mono for Android) compatibility
- * [THRIFT-1702] - a thrift manual
- * [THRIFT-1694] - Re-Enable serialization for WP7 Silverlight
- * [THRIFT-1691] - Serializer/deserializer support for Delphi
- * [THRIFT-1688] - Update IDL page markup
- * [THRIFT-1725] - Tutorial web pages for Delphi and C#
- * [THRIFT-1714] - [ruby] Explicitly add CWD to Ruby test_suites.rb
- * [THRIFT-317] - Issues with Java struct validation
- * [THRIFT-164] - Build web tutorial on Incubator web site
- * [THRIFT-541] - Cocoa code generator doesn't put keywords before all arguments.
- * [THRIFT-681] - The HTML generator does not handle JavaDoc style comments very well
-
-## New Feature
- * [THRIFT-1500] - D programming language support
- * [THRIFT-1510] - There should be an implementation of the JsonProtocol for ruby
- * [THRIFT-1115] - python TBase class for dynamic (de)serialization, and __slots__ option for memory savings
- * [THRIFT-1953] - support for asp.net mvc 3
-
-## Question
- * [THRIFT-1235] - How could I use THttpServerTransportFactory withTNonBlockingServer
- * [THRIFT-1368] - TNonblockingServer usage
- * [THRIFT-1061] - Read an invalid frame size of 0. Are you using TFramedTransport on the client side?
- * [THRIFT-491] - Ripping raw pthreads out of TFileTransport and associated test issues
-
-## Sub-task
- * [THRIFT-1596] - Delphi: Test clients should have a return codes that reflect whether they succeeded or not
- * [THRIFT-982] - javame: add version Info to the library
- * [THRIFT-1722] - C# WP7 Assembly addition beaks mono build
- * [THRIFT-336] - Compact Protocol in C#
-
-## Test
- * [THRIFT-1613] - Add code back into empty source file ToStringTest.java
- * [THRIFT-1718] - Incorrect check in TFileTransportTest
-
-## Wish
- * [THRIFT-1463] - Decouple Thrift IDL from generators
- * [THRIFT-1466] - Proper Documentation for Thrift C Glib
- * [THRIFT-1539] - Build and distribute the fb303 python libraries along with thrift
- * [THRIFT-1685] - Please add "aereo.com" to "Powered by Apache Thrift" list in about page
- * [THRIFT-330] - TProcessor - additional method to called when connection is broken
-
-
-
-Thrift 0.8
---------------------------------------------------------------------------------
-## Bug
- * [THRIFT-1436] - pip install thrift fails on Windows with "Unable to find vcvarsall.bat"
- * [THRIFT-1432] - Javascript struct constants declared in the same file as their struct definition will cause an error
- * [THRIFT-1428] - shared.thrft does not include namespace for php, so thrift compiler generate incorrect name
- * [THRIFT-1426] - Dist package missing files for release 0.8
- * [THRIFT-1425] - The Node package is incompatible with latest node (0.6) & npm (1.0.27)
- * [THRIFT-1416] - Python Unit test is broken on ci
- * [THRIFT-1419] - AbstractNonBlockingServer does not catch errors when invoking the processor
- * [THRIFT-1424] - Ruby specs fail when run with rake
- * [THRIFT-1420] - Nonblocking and HsHa server should make sure to close all their socket connections when the selector exits
- * [THRIFT-1413] - Generated code does not read MapEnd / ListEnd / SetEnd
- * [THRIFT-1409] - Name conflict check does not work properly for exception object(Delphi).
- * [THRIFT-1408] - Delphi Test Server: Exception test case fails due to naming conflict with e.message
- * [THRIFT-1407] - Typo in Python socket server causes Thrift to fail when we enable a global socket timout
- * [THRIFT-1397] - CI server fails during build due to unused parameters in delphi generator
- * [THRIFT-1404] - Delphi compiler generates struct reader code with problem.
- * [THRIFT-1400] - Ruby native extension aborts with __stack_chk_fail in OSX
- * [THRIFT-1399] - One of the TServerImpl.Create CTORs lacks implementation
- * [THRIFT-1390] - Debian packages build fix for Squeeze (build from the official 0.7.0 tarball)
- * [THRIFT-1393] - TTransportException's thrown from THttpClient contain superfluous slashes in the Exception message
- * [THRIFT-1392] - Enabling both namespaces and autoloading in generated PHP code won't work.
- * [THRIFT-1406] - Build error after applying THRIFT-1395
- * [THRIFT-1405] - Delphi compiler does not generates container serializer properly.
- * [THRIFT-1411] - java generator does not provide type parameter for TBaseProcessor
- * [THRIFT-1473] - JSON context stack may be left in an incorrect state when an exception is thrown during read or write operations
- * [THRIFT-1331] - Ruby library deserializes an empty map to nil
- * [THRIFT-1330] - PHP Namespaces no longer generated
- * [THRIFT-1328] - TBaseHelper.toString(...) appends ByteBuffer data outside of valid buffer range
- * [THRIFT-1322] - OCaml lib fail to compile: Thrift.ml line 305, int vs int32 mismatch
- * [THRIFT-1143] - Build doesn't detect correct architecture type on 64bit osx
- * [THRIFT-1205] - port server unduly fragile with arbitrary input
- * [THRIFT-1279] - type set is handled incorrectly when writing object
- * [THRIFT-1298] - Standard scheme doesn't read or write metadata along with field values
- * [THRIFT-1265] - C++ container deserialize
- * [THRIFT-1263] - publish ruby client to rubygems
- * [THRIFT-1384] - Java help menu missing newline near javame flag
- * [THRIFT-1382] - Bundle install doesnot work because thrift crashes
- * [THRIFT-1381] - Thrift C++ libs have incorrectly versioned names
- * [THRIFT-1350] - Go library code does not build as of r60 (most recent release)
- * [THRIFT-1365] - TupleProtocol#writeBitSet unintentionally writes a variable length byte array
- * [THRIFT-1359] - --gen-cob cpp:cob_style does not compile anymore
- * [THRIFT-1319] - Mismatch between how a union reads and writes a container
- * [THRIFT-1309] - libfb303-0.7.0.jar missing in maven repository
- * [THRIFT-1238] - Thrift JS client cannot read map of structures
- * [THRIFT-1254] - Code can't be compiled against a regular JRE: Object.clone() override has a different return type
- * [THRIFT-1367] - Mac OSX build fails with "no such file to load -- spec/rake/spectask"
- * [THRIFT-1355] - Running make in lib/rb doesn't build the native extensions
- * [THRIFT-1370] - Debian packaging should Build-Depend on libglib2.0-dev
- * [THRIFT-1342] - Compilation problem on Windows of fastbinary.c
- * [THRIFT-1341] - TProtocol.h endian detection wrong with boost
- * [THRIFT-1583] - c_glib leaks memory
- * [THRIFT-1582] - Bad includes of nested thrift files in c_glib
- * [THRIFT-1578] - C_GLib generated code does not compile
- * [THRIFT-1027] - 'make -j 16' fails with "unterminated #ifdef" error
- * [THRIFT-1121] - Java server performance regression in 0.6
- * [THRIFT-857] - tests run by "make install" fail if generators are disabled
- * [THRIFT-380] - Use setuptools for python build
-
-## Dependency upgrade
- * [THRIFT-1257] - thrift's dependency scope on javax.servlet:servlet-api should be 'provided'
-
-## Improvement
- * [THRIFT-1445] - minor C++ generator variable cleanup
- * [THRIFT-1435] - make TException.Message property conformant to the usual expectations
- * [THRIFT-1431] - Rename 'sys' module to 'util'
- * [THRIFT-1396] - Dephi generator has dependacy on boost 1.42 later.
- * [THRIFT-1395] - Patch to prevent warnings for integer types in some cases
- * [THRIFT-1275] - thrift: always prefix namespaces with " ::"
- * [THRIFT-1274] - thrift: fail compilation if an unexpected token is
- * [THRIFT-1271] - thrift: fix missing namespace in generated local
- * [THRIFT-1270] - thrift: add --allow-neg-keys argument to allow
- * [THRIFT-1345] - Allow building without tests
- * [THRIFT-1286] - Modernize the Thrift Ruby Library Dev Environment
- * [THRIFT-1284] - thrift: fix processor inheritance
- * [THRIFT-1283] - thrift: wrap t_cpp_generator::generate_process_function() to 80
- * [THRIFT-1282] - Upgrade httpclient to 4.1.2 (from 4.0.1)
- * [THRIFT-1281] - add @generated to the docblock
- * [THRIFT-1280] - Thrift: Improve Monitor exception-free interfaces
- * [THRIFT-1278] - javadoc warnings - compilation
- * [THRIFT-1227] - Erlang implementation of thrift JSON protocol
- * [THRIFT-1295] - Duplicate include in TSocket.cpp
- * [THRIFT-1294] - thrift: fix log message typos in TSimpleServer
- * [THRIFT-1293] - thrift: improve handling of exceptions thrown by
- * [THRIFT-1292] - thrift: silence log spew from TThreadedServer
- * [THRIFT-1288] - Allow typedefed exceptions in throws clauses
- * [THRIFT-1290] - thrift: TNonblockingServer: clean up state in the
- * [THRIFT-1287] - thrift: start refactoring some of the C++ processor
- * [THRIFT-1289] - thrift: implement TNonblockingServer::stop()
- * [THRIFT-1305] - thrift: make TConnection a private inner class of
- * [THRIFT-1304] - TNonblockingServer: pass in the connection context to
- * [THRIFT-1302] - thrift: raise an exception if send() times out in
- * [THRIFT-1301] - thrift: consolidate common code in TNonblockingServer
- * [THRIFT-1377] - abort PHP deserialization on unknown field type
- * [THRIFT-1379] - fix uninitialized enum values in thrift C++ objects
- * [THRIFT-1376] - Make port specification option in thrift remote
- * [THRIFT-1375] - fixed a hex char conversion bug in TJSONProtocol
- * [THRIFT-1373] - Fix user-defined exception generation in thrift (python)
- * [THRIFT-1361] - Optional replacement of pthread by boost::thread
- * [THRIFT-1320] - Consistency of configure generated config.h
- * [THRIFT-1317] - Remove copy constructibility from
- * [THRIFT-1316] - thrift: update server classes to accept
- * [THRIFT-1315] - thrift: generate server interface factory classes
- * [THRIFT-1314] - thrift: add TProcessorFactory
- * [THRIFT-1335] - Add accept timeout to TServerSocket
- * [THRIFT-1334] - Add more info to IllegalStateException
- * [THRIFT-1333] - Make RWGuard not copyable
- * [THRIFT-1332] - TSSLTransportParameters class uses hard coded value keyManagerType: SunX509
- * [THRIFT-1251] - Generated java code should indicate which fields are required and which are optional
- * [THRIFT-1387] - Build MSVC libraries with Boost Threads instead of Pthreads
- * [THRIFT-1339] - Extend Tuple Protocol to TUnions
- * [THRIFT-1031] - Patch to compile Thrift for vc++ 9.0 and 10.0
- * [THRIFT-1130] - Add the ability to specify symbolic default value for optional boolean
- * [THRIFT-1123] - Patch to compile Thrift server and client for vc++ 9.0 and 10.0
- * [THRIFT-386] - Make it possible to build the Python library without the extension
-
-## New Feature
- * [THRIFT-1401] - JSON-protocol for Delphi XE Libraries
- * [THRIFT-1167] - Java nonblocking server with more than one thread for select and handling IO
- * [THRIFT-1366] - Delphi generator, lirbrary and unit test.
- * [THRIFT-1354] - Add rake task to build just the gem file
- * [THRIFT-769] - Pluggable Serializers
-
-## Sub-task
- * [THRIFT-1415] - delphi: add version Info to the library
- * [THRIFT-1391] - Improved Delphi XE test cases
-
-
-
-Thrift 0.7
---------------------------------------------------------------------------------
-## Bug
- * [THRIFT-1140] - Framed Transport Client using C (Glib) Library hangs when connecting to Ruby Server
- * [THRIFT-1154] - HttpClient does not specify the connection close parameter
- * [THRIFT-1153] - HttpClient does not specify the connection close parameter
- * [THRIFT-1149] - Nonblocking server fails when client connection is reset
- * [THRIFT-1146] - Android Incompatibility : in Android < 2.3 java.io.IOException doesn't support for Throwable parameter in constructor
- * [THRIFT-1133] - Java and JavaScript tutorial is broken since we have Java maven deployment
- * [THRIFT-1132] - Deserialization error in TApplicationException C#
- * [THRIFT-1131] - C# JSON Protocol is unable to decode escaped characters in string
- * [THRIFT-1208] - python TCompactProtocol.py writeBool and readBool not follow the compact-proto-spec-2.txt spec for CONTAINER_WRITE, CONTAINER_READ
- * [THRIFT-1200] - JS compiler generates code that clobbers existing namespaces
- * [THRIFT-1183] - Pure-ruby CompactProtocol raises ArgumentError when deserializing under Ruby 1.9
- * [THRIFT-1182] - Native deserializer segfaults on incorrect list element type
- * [THRIFT-1181] - AS3 compiler generates incorrect code for setting default values in constructor
- * [THRIFT-1234] - thrift --help is missing doc on py:utf8strings
- * [THRIFT-1180] - AS3 compiler generates uncompilable code for binary types.
- * [THRIFT-1194] - Java lib does not install artifacts to local dir correctly
- * [THRIFT-1193] - Potential infinite loop in nonblocking_server
- * [THRIFT-1192] - Typo: TProtocol.h tests for HAVE_SYS_PARAM_H_
- * [THRIFT-1190] - readBufferBytesAllocated in TNonblockingServer.java should be AtomicLong to fix FD leakage and general server malfunction
- * [THRIFT-1187] - nonblocking_server shutdown race under Ruby 1.9
- * [THRIFT-1178] - Java: TBase signature should be T extends TBase<?,?>
- * [THRIFT-1164] - Segmentation fault on NULL pointer in t_js_generator::generate_const
- * [THRIFT-1171] - Perl write/readDouble assumes little-endian platform
- * [THRIFT-1222] - Unhandled exception for TEvhttpServer request
- * [THRIFT-1220] - TProcessor::process never returns false
- * [THRIFT-1285] - Stable 0.7.0 Windows compiler exe available on the webside is not the good one
- * [THRIFT-1218] - c_glib uses wrong name in pkg-config
- * [THRIFT-1215] - Undefined property Thirft in lib/js/thrift.js
- * [THRIFT-1211] - When using THttpClient, non 200 responses leave the connection open
- * [THRIFT-1228] - The php accelerator module calls flush incorrectly
- * [THRIFT-1308] - libfb303-0.7.0.jar missing in maven repository
- * [THRIFT-1255] - Mismatch of method name between JavaME's lib and generated code (compareTo/compareObjects)
- * [THRIFT-1253] - Code generated for maps is not compiling
- * [THRIFT-1252] - Segfault in Ruby deserializer
- * [THRIFT-1094] - bug in TCompactProto python readMessageEnd method and updated test cases
- * [THRIFT-1093] - several bugs in python TCompactProtocol
- * [THRIFT-1092] - generated validate() method has wrong indentation
- * [THRIFT-1011] - Error generating package imports when using classes from other packages
- * [THRIFT-1050] - Declaring an argument named "manager" to a service method produces code that fails compile due to name conflicts with protected ivars in TAsyncClient
- * [THRIFT-1074] - .keystore and .truststore are missing from the 0.6.0 distribution
- * [THRIFT-1067] - Tons of bugs in php implementation
- * [THRIFT-1065] - Unexpected exceptions not proper handled on JS
- * [THRIFT-1076] - Erlang Thrift socket server has a bug that causes java thrift client of framed binary client to throw "out of sequence" exception
- * [THRIFT-1057] - casts in TBinaryProtocol.tcc causing "dereferencing type-punned pointer will break strict-aliasing rules" warnings from gcc
- * [THRIFT-1055] - csharp TServerSocket and TSocket do not disable Nagle via Socket.NoDelay = true like cpp and java do
- * [THRIFT-1054] - explicit call to PKG_PROG_PKG_CONFIG is missing and first use of PKG_CHECK_MODULES may not happen, causes mono detection to fail
- * [THRIFT-1117] - JavaScript Unit Test does not work anymore because libthrift*.jar where moved by Maven Deployment
- * [THRIFT-1111] - The HTML generator does not distinguish between string and binary types
- * [THRIFT-1032] - "make dist" fails due to c_glib problem
- * [THRIFT-1036] - Auto-generated C++ code fails to compile with "-Werror -Wextra -Wall" g++ compiler flags
- * [THRIFT-1041] - TDeserializer holds onto a reference of the array it reads after it is done deserializing
- * [THRIFT-1106] - C++ code TAsyncProtocolProcessor.h & TAsyncBufferProcessor.h dont have virtual functions but no virtual destructor. Causes warnings on -Wall
- * [THRIFT-1105] - OCaml generator does not prefix methods of included structs with their type
- * [THRIFT-1104] - INSTALLDIRS should be included in configure script
- * [THRIFT-1102] - typo in configure.ac: "==" operator in 'test' (instead of"'=")
- * [THRIFT-1101] - bytebuffer length calculation in TBinaryProtocol writeBinary
- * [THRIFT-1098] - Undefined properties in TBinaryProtocolFactory
- * [THRIFT-1081] - PHP tests broken and somewhat incomplete
- * [THRIFT-1080] - erlang test's 'make' fails on Mac OSX
- * [THRIFT-1078] - ThriftTest.thrift generates invalid PHP library
- * [THRIFT-1120] - proto.WriteListEnd being called in the wrong place
- * [THRIFT-1119] - TJSONProtocol fails to UTF8 decode strings
- * [THRIFT-867] - PHP accelerator module's output transport is incompatible with TFramedTransport
- * [THRIFT-826] - PHP TSocket Write Timeout
- * [THRIFT-835] - Bad AS3 syntax in constructors that set default values
- * [THRIFT-788] - thrift_protocol.so: multiget/multiget_slice does not handle more than 17 keys correctly
- * [THRIFT-125] - OCaml libraries don't compile with 32-bit ocaml
- * [THRIFT-342] - PHP: can't have sets of complex types
- * [THRIFT-731] - configure doesn't check for ant >= 1.7
- * [THRIFT-690] - Update TApplicationException codes
- * [THRIFT-638] - BufferedTransport + C extensions block until recv timeout is reached on last fread call
-
-## Dependency upgrade
- * [THRIFT-1177] - Update thrift to reflect changes in Go's networking libraries
-
-## Improvement
- * [THRIFT-1155] - Remove log4j dependency from java client
- * [THRIFT-1151] - Produce more informative runtime error in case of schema and data mismatch during serialization
- * [THRIFT-1207] - Support DESTDIR on "make install" of ruby libs
- * [THRIFT-1199] - Union structs should have generated methods to test whether a specific field is currently set
- * [THRIFT-1233] - Remove unused include in generated C++ code
- * [THRIFT-1189] - Ruby deserializer speed improvements
- * [THRIFT-1170] - Thrift Generated Code and Java 5
- * [THRIFT-1174] - Publish as3 client implementation via Maven for use by flex-mojos users
- * [THRIFT-1225] - TCompactProtocol for PHP
- * [THRIFT-1221] - Remove SimpleCallback.h
- * [THRIFT-1217] - Use evutil_socketpair instead of pipe (Windows port)
- * [THRIFT-1216] - build Java Library behind a proxy
- * [THRIFT-1231] - Remove bogus include
- * [THRIFT-1213] - Membuffer should provide a way to get back the buffer
- * [THRIFT-1237] - Java fb303 missing some methods
- * [THRIFT-1063] - Fix Erlang Tutorial Files
- * [THRIFT-1053] - Make remote client's IP address available for all socket related transports
- * [THRIFT-1109] - Deploy fb303 along side libthrift to maven repo
- * [THRIFT-1107] - improvement for compiler-generated python for 'None' object comparisons
- * [THRIFT-1069] - Add command line option to prevent thrift from inserting gen-* directories
- * [THRIFT-1049] - Allow for TServerSocket python library to bind to a specific host
- * [THRIFT-1126] - Extending struct_info for erlang bindings
- * [THRIFT-1100] - python TSSLSocket improvements, including certificate validation
- * [THRIFT-994] - Don't try to invoke phpize if we don't have it
- * [THRIFT-993] - Some improvements in C++ stubs for oneway operations
- * [THRIFT-997] - Using valueOf for base types in getFieldValue
- * [THRIFT-418] - Don't do runtime sorting of struct fields
- * [THRIFT-151] - TSSLServerSocket and TSSLSocket implementation
- * [THRIFT-27] - Generated erlang types don't contain default values for records
- * [THRIFT-113] - to-string methods should omit optional null fields from output
- * [THRIFT-363] - Maven Deploy
- * [THRIFT-447] - Make an abstract base Client class so we can generate less code
- * [THRIFT-627] - should c++ have setters for optional fields?
-
-## New Feature
- * [THRIFT-1236] - Erlang Reconnecting Thrift Client
- * [THRIFT-1021] - Framed transport support for OCaml
- * [THRIFT-1068] - Python SSL Socket Support
- * [THRIFT-1103] - TZlibTransport for python, a zlib compressed transport
- * [THRIFT-1083] - Preforking python process pool server
- * [THRIFT-999] - Add TForkingServer
-
-## Sub-task
- * [THRIFT-1152] - Attributes from private to protected
- * [THRIFT-1038] - Generated Java code for structures containing binary fields (or collections thereof) are not serializable (in the Java sense) even though they implement java.io.Serializable
-
-## Task
- * [THRIFT-892] - Refactor erlang build system with rebar
-
-## Wish
- * [THRIFT-625] - Add support for 'Go'
-
-
-
-Thrift 0.6.1
---------------------------------------------------------------------------------
-## Bug
- * [THRIFT-1133] - Java and JavaScript tutorial is broken since we have Java maven deployment
- * [THRIFT-1131] - C# JSON Protocol is unable to decode escaped characters in string
- * [THRIFT-1074] - .keystore and .truststore are missing from the 0.6.0 distribution
-
-## Improvement
- * [THRIFT-1109] - Deploy fb303 along side libthrift to maven repo
- * [THRIFT-363] - Maven Deploy
-
-## Question
- * [THRIFT-1206] - did the THRIFT 0.6.1 merge THRIFT-563 ?
-
-## Sub-task
- * [THRIFT-1163] - How can i use multi service in one program?
-
-## Task
- * [THRIFT-1112] - Apply THRIFT-363 to 0.6 branch
- * [THRIFT-1113] - Apply THRIFT-1074 to 0.6 branch
-
-
-
-Thrift 0.6
---------------------------------------------------------------------------------
-## Bug
- * [THRIFT-1020] - OCaml compiler generates invalid OCaml
- * [THRIFT-1015] - TUnion does not handle ByteBuffer in toString
- * [THRIFT-1013] - generated java code may have name clashes with thrift library
- * [THRIFT-1009] - TUnion does not correctly deep copy a ByteBuffer
- * [THRIFT-1032] - "make dist" fails due to c_glib problem
- * [THRIFT-868] - Referencing constant values doesn't work with with typedef types
- * [THRIFT-971] - java module can't be compiled without ivy and network connection
- * [THRIFT-970] - Under heavy load, THttpClient may fail with "too many open files"
- * [THRIFT-969] - Java Tutorial broken, move CalculatorHandler to a separate file
- * [THRIFT-807] - JavaScript: Initialization of Base Types with 0 instead of null
- * [THRIFT-955] - Thrift compiler for Windows uses lowercase names and directories which is inconsistent with compiling on other platforms
- * [THRIFT-992] - Naming convention in C# constructor is not consistent with other fields causes compile errors
- * [THRIFT-1008] - byte[] accessors throw NPE on unset field
- * [THRIFT-1006] - Impossible to correctly qualify an enum constant in an external thrift file
- * [THRIFT-950] - Haskell bindings treat 'byte' as unsigned 8-bit int (Data.Word.Word8), java/cpp as signed (byte/int8_t).
- * [THRIFT-975] - lib/c_glib/README is missing => breaks make dist
- * [THRIFT-944] - Support all version-4s of base
- * [THRIFT-939] - optional binary fields throw NPE on default byte[] getters
- * [THRIFT-935] - PHP Extension aborts the build if php-config is not installed
- * [THRIFT-933] - Haskell's Thrift.cabal has warnings
- * [THRIFT-932] - Haskell tests need to be run through 'make check' (and probably 'cabal check') too
- * [THRIFT-904] - C# TSocket should disable nagle and linger
- * [THRIFT-941] - Make PHP C Extension use the defined Protocol writeMessageBegin function
- * [THRIFT-940] - 'make check' fails if boost is not in the std include and link paths
- * [THRIFT-924] - Fix generated php structure constants
- * [THRIFT-979] - ruby bindings used to work on jruby
- * [THRIFT-977] - Hex Conversion Bug in C++ TJSONProtocol
- * [THRIFT-347] - PHP TSocket Timeout Issues
- * [THRIFT-517] - TExceptions thrown by server result in cryptic error message on client - Tried to read 4 bytes, but only got 0 bytes
-
-## Improvement
- * [THRIFT-1024] - Add Python Twisted example to the Tutorial
- * [THRIFT-958] - Change accessmodifer on trans_ field in the FrameBuffer class to public.
- * [THRIFT-957] - THsHaServer: Change access modifier of the invoker field.
- * [THRIFT-1002] - CodeStyle: t_c_glib_generator.cc
- * [THRIFT-1005] - Give unions byte[] signature methods to go along with their ByteBuffer counterparts
- * [THRIFT-951] - Add a new isServing() method to TServer
- * [THRIFT-943] - Silly readme typo fix.
- * [THRIFT-961] - JavaScript TestSuite using ant/ivy and Java's ServerTestBase Handler
- * [THRIFT-960] - add TestServer, TestNonblockingServer and TestClient again
- * [THRIFT-949] - Modify the TEnum interface so it defines a method similar to findByValue
- * [THRIFT-946] - Augment FieldValueMetaData so it differentiates 'string' and 'binary' fields.
- * [THRIFT-903] - custom ThreadFactory in THsHaServer
- * [THRIFT-913] - Test Case for Url encoded strings + simple enhancement to lib/js/test/RunTestServer.sh
- * [THRIFT-926] - Miscellaneous C++ improvements
- * [THRIFT-929] - Improvements to the C++ test suite
- * [THRIFT-893] - add JavaScript to the tutorial examples
- * [THRIFT-1003] - Polishing c_glib code
- * [THRIFT-71] - Debian packaging for thrift
-
-## New Feature
- * [THRIFT-1033] - Node.js language target
- * [THRIFT-947] - Provide a helper method to determine the TProtocol used to serialize some data.
- * [THRIFT-928] - Make more statistics available in C++ servers
- * [THRIFT-922] - Templatized [de]serialization code for C++
- * [THRIFT-923] - Event-driven client and server support for C++
- * [THRIFT-925] - Provide name<->value map for enums in C++
- * [THRIFT-927] - Add option to modify the PHP include path
- * [THRIFT-377] - TFileTransport port in Java
- * [THRIFT-106] - TSSLServerSocket
- * [THRIFT-582] - C implementation of Thrift
- * [THRIFT-745] - Make it easier to instantiate servers
-
-## Sub-task
- * [THRIFT-1038] - Generated Java code for structures containing binary fields (or collections thereof) are not serializable (in the Java sense) even though they implement java.io.Serializable
-
-## Task
- * [THRIFT-862] - Async client issues / improvements
-
-## Test
- * [THRIFT-581] - Add a testsuite for txThrift (Twisted)
-
-
-
-Thrift 0.5.0 - Incubating
---------------------------------------------------------------------------------
-THRIFT-505 Build Make configure give a summary of the enabled components (David Reiss)
-THRIFT-506 Build Allow Thrift to be built without the C++ library (David Reiss)
-THRIFT-844 Build Build Requirements state autoconf 2.59+ is required, but 2.60+ is needed (Harlan Lieberman-Berg)
-THRIFT-850 Build Perl runtime requires Bit::Vector which may not be installed by default, but configure does not fail (Michael Lum)
-THRIFT-854 Build Provide configure option and make rules to build/install php extension (Anthony Molinaro)
-THRIFT-858 Build Have bootstrap.sh check for a suitable autoconf version before running (David Reiss)
-THRIFT-871 Build Thrift compiler for WIndows (binary distribution) (David Reiss)
-THRIFT-323 C# TJSONProtocol (Roger Meier)
-THRIFT-634 C# C# Compiler Generates Incorrect Code For Fields which begin with an uppercase letter (Jon S Akhtar)
-THRIFT-881 C# add csharp to the tutorial (Roger Meier)
-THRIFT-856 C++ Building cpp library fails on OS X with malloc and free not being declared in scope (James Clarke)
-THRIFT-865 C++ C++ compiler build depends on libfl even when flex/lex not detected (David Reiss)
-THRIFT-900 C++ Unix domain socket (Roger Meier)
-THRIFT-920 C++ C++ Test and Tutorial does not compile anymore due to the change within Enum handling (Roger Meier)
-THRIFT-567 C++ Can't immediately stop a TSimpleServer thread that is idle (Rush Manbert)
-THRIFT-756 C++ Exposing TSocket(int) constructor to public (Rajat Goel)
-THRIFT-798 C++ TNonblockingServer leaks resources when destroyed (David Reiss)
-THRIFT-812 C++, Python Demo of Thrift over ZeroMQ (David Reiss)
-THRIFT-629 Cocoa Unused Field In TSocketServer Appears To Break iPhone Build (Jon S Akhtar)
-THRIFT-838 Cocoa Generated Cocoa classes have useless @dynamic declarations (Kevin Ballard)
-THRIFT-805 Cocoa Don't generate process_XXXX methods for oneway methods (Brad Taylor)
-THRIFT-507 Compiler Remove the compiler's dependency on Boost (David Reiss)
-THRIFT-895 Compiler (General) Thrift compiler does not allow two different enumerations to have the same key name for one of the enum values (David Reiss)
-THRIFT-852 Compiler (General) Missing newline causes many compiler warnings (Anthony Molinaro)
-THRIFT-877 Compiler (General) smalltalk namespace doesn't work (Bruce Lowekamp)
-THRIFT-897 Compiler (General) Don't allow unqualified constant access to enum values (Bryan Duxbury)
-THRIFT-9 Compiler (General) Add a default namespace declaration for all languages (David Reiss)
-THRIFT-599 Erlang Don't use unnecessary processes in the Erlang transports and clients (David Reiss)
-THRIFT-646 Erlang Erlang library is missing install target (David Reiss)
-THRIFT-698 Erlang Generated module list should contain atoms, not strings (Anthony Molinaro)
-THRIFT-866 Erlang term() in spec definitions seems to not work in erlang R12 (Anthony Molinaro)
-THRIFT-886 Erlang Dialyzer warning (Anthony Molinaro)
-THRIFT-785 Erlang Framed transport server problems (Anthony Molinaro)
-THRIFT-884 HTML HTML Generator: add Key attribute to the Data Types Tables (Roger Meier)
-THRIFT-652 Haskell Generated field name for strut is not capitalized correctly (Christian Lavoie)
-THRIFT-743 Haskell compile error with GHC 6.12.1 (Christian Lavoie)
-THRIFT-901 Haskell Allow the bindings to compile without -fglasgow-exts and with -Wall -Werror (Christian Lavoie)
-THRIFT-905 Haskell Make haskell thrift bindings use automake to compile and install (Christian Lavoie)
-THRIFT-906 Haskell Improve type mappings (Christian Lavoie)
-THRIFT-914 Haskell Make haskell bindings 'easily' compilable (Christian Lavoie)
-THRIFT-918 Haskell Make haskell tests run again (Christian Lavoie)
-THRIFT-919 Haskell Update Haskell bindings README (Christian Lavoie)
-THRIFT-787 Haskell Enums are not read correctly (Christian Lavoie)
-THRIFT-250 Java ExecutorService as a constructor parameter for TServer (Ed Ceaser)
-THRIFT-693 Java Thrift compiler generated java code that throws compiler warnings about deprecated methods. (Bryan Duxbury)
-THRIFT-843 Java TNonblockingSocket connects without a timeout (Bryan Duxbury)
-THRIFT-845 Java async client does not respect timeout (Ning Liang)
-THRIFT-870 Java Java constants don't get Javadoc comments (Bryan Duxbury)
-THRIFT-873 Java Java tests fail due to Too many open files (Todd Lipcon)
-THRIFT-876 Java Add SASL support (Aaron T. Myers)
-THRIFT-879 Java Remove @Override from TUnion.clear (Dave Engberg)
-THRIFT-882 Java deep copy of binary fields does not copy ByteBuffer characteristics (arrayOffset, position) (Bryan Duxbury)
-THRIFT-888 Java async client should also have nonblocking connect (Eric Jensen)
-THRIFT-890 Java Java tutorial doesn't work (Todd Lipcon)
-THRIFT-894 Java Make default accessors for binary fields return byte[]; provide new accessors to get ByteBuffer version (Bryan Duxbury)
-THRIFT-896 Java TNonblockingSocket.isOpen() returns true even after close() (Eric Jensen)
-THRIFT-907 Java libfb303 doesn't compile in 0.4.0 (Todd Lipcon)
-THRIFT-912 Java Improvements and bug fixes to SASL implementation (Todd Lipcon)
-THRIFT-917 Java THsHaServer should not accept an ExecutorService without catching RejectedExecutionException (Ed Ceaser)
-THRIFT-931 Java Use log4j for Java tests (Todd Lipcon)
-THRIFT-880 JavaME JavaME code generator and runtime library (Dave Engberg)
-THRIFT-846 JavaScript JavaScript Test Framwork: extended Testcases (Roger Meier)
-THRIFT-885 JavaScript Url encoded strings never get decoded? How do we fix this? (T Jake Luciani)
-THRIFT-911 JavaScript (JavaScript compiler) Const structs, maps, sets, and lists generate a trailing comma (T Jake Luciani)
-THRIFT-860 OCaml copy method and reset method (Lev Walkin)
-THRIFT-682 PHP PHP extension doesn't compile on Mac OS X (Bryan Duxbury)
-THRIFT-851 PHP php extension fails to compile on centos 5.x (Todd Lipcon)
-THRIFT-840 Perl Perl protocol handler could be more robust against unrecognised types (Conrad Hughes)
-THRIFT-758 Perl incorrect deference in exception handling (Yann Kerherve)
-THRIFT-257 Python Support validation of required fields (Esteve Fernandez)
-THRIFT-335 Python Compact Protocol for Python (David Reiss)
-THRIFT-596 Python Make Python's TBufferedTransport use a configurable input buffer (David Reiss)
-THRIFT-597 Python Python THttpServer performance improvements (David Reiss)
-THRIFT-598 Python Allow Python's threading servers to use daemon threads (David Reiss)
-THRIFT-666 Python Allow the handler to override HTTP responses in THttpServer (David Reiss)
-THRIFT-673 Python Generated Python code has whitespace issues (Ian Eure)
-THRIFT-721 Python THttpClient ignores url parameters (Thomas Kho)
-THRIFT-824 Python TApplicationException.__str__() refers to class constants as globals (Peter Schuller)
-THRIFT-855 Python Include optimized compiled python objects in install (Anthony Molinaro)
-THRIFT-859 Python Allow py:twisted to be generated in different namespace than py (Bruce Lowekamp)
-THRIFT-869 Python TSocket.py on Mac (and FreeBSD) doesn't handle ECONNRESET from recv() (Steven Knight)
-THRIFT-875 Python Include python setup.cfg in dist (Anthony Molinaro)
-THRIFT-610 Ruby binary_protocol.rb segfaults [line 86] (Unassigned)
-THRIFT-899 Ruby Ruby read timeouts can sometimes be 2x what they should be (Ryan King)
-THRIFT-909 Ruby allow block argument to struct constructor (Michael Stockton)
-THRIFT-456 Test Suite Bad IP address string in test/cpp/src/main.cpp (Rush Manbert)
-
-
-Thrift 0.4.0 - Incubating
---------------------------------------------------------------------------------
-THRIFT-650 Build Make Check fails on Centos/OSX with 0.2.0 tarball (Anthony Molinaro)
-THRIFT-770 Build Get 'make dist' to work without first compiling source code (Anthony Molinaro)
-THRIFT-160 C# Created THttpTransport for the C# library based on WebHttpRequest (Michael Greene)
-THRIFT-834 C# THttpClient resends contents of message after transport errors (Anatoly Fayngelerin)
-THRIFT-247 C++ THttpServer Transport (Unassigned)
-THRIFT-676 C++ Change C++ code generator so that generated classes can be wrapped with SWIG (Unassigned)
-THRIFT-570 Compiler Thrift compiler does not error when duplicate method names are present (Bruce Simpson)
-THRIFT-808 Compiler Segfault when constant declaration references a struct field that doesn't exist (Bryan Duxbury)
-THRIFT-646 Erlang Erlang library is missing install target (Anthony Molinaro)
-THRIFT-544 General multiple enums with the same key generate invalid code (Ben Taitelbaum)
-THRIFT-434 General ruby compiler should warn when a reserved word is used (Michael Stockton)
-THRIFT-799 General Files missing proper Apache license header (Bryan Duxbury)
-THRIFT-832 HTML HTML generator shows unspecified struct fields as 'required' (Bryan Duxbury)
-THRIFT-226 Java Collections with binary keys or values break equals() (Bryan Duxbury)
-THRIFT-484 Java Ability to use a slice of a buffer instead of a direct byte[] for binary fields (Bryan Duxbury)
-THRIFT-714 Java maxWorkerThreads parameter to THsHaServer has no effect (Bryan Duxbury)
-THRIFT-751 Java Add clear() method to TBase (Bryan Duxbury)
-THRIFT-765 Java Improved string encoding and decoding performance (Bryan Duxbury)
-THRIFT-768 Java Async client for Java (Bryan Duxbury)
-THRIFT-774 Java TDeserializer should provide a partialDeserialize method for primitive types (Piotr Kozikowski)
-THRIFT-783 Java .equals java method is broken on structs containing binary-type fields (Unassigned)
-THRIFT-804 Java CompareTo is broken for unions set to map, set, or list (Bryan Duxbury)
-THRIFT-814 Java Include a TServlet in the standard Thrift distribution (Mathias Herberts)
-THRIFT-818 Java Async client doesn't send method args (Bryan Duxbury)
-THRIFT-830 Java Switch binary field implementation from byte[] to ByteBuffer (Bryan Duxbury)
-THRIFT-831 Java FramedTransport implementation that reuses its buffers (Bryan Duxbury)
-THRIFT-833 Java build.xml in lib/java is missing a classpathref attribute for the javadoc task (Bryan Duxbury)
-THRIFT-836 Java Race condition causes CancelledKeyException in TAsyncClientManager (Bryan Duxbury)
-THRIFT-842 Java Upgrade to current version of commons-lang (2.5 instead of 2.4) and/or change dependency in ivy.xml to not be exact (Bryan Duxbury)
-THRIFT-815 JavaScript Deserialization of lists is critically broken. (T Jake Luciani)
-THRIFT-827 OCaml OCaml generator to take default values into account (Lev Walkin)
-THRIFT-647 PHP PHP library is missing install target (Anthony Molinaro)
-THRIFT-682 PHP PHP extension doesn't compile on Mac OS X (Bryan Duxbury)
-THRIFT-718 PHP Thrift PHP library includes closing tags and extraneous whitespace (Nicholas Telford)
-THRIFT-778 PHP PHP socket listening server (Nick Jones)
-THRIFT-780 PHP PHP extension sometimes causes an abort with two exceptions at the same time (David Reiss)
-THRIFT-837 PHP PHP accelerator bug for writes > 8k (Thomas Kho)
-THRIFT-782 Perl Perl code for writing containers doesn't count length of write*Begin or write*End (Conrad Hughes)
-THRIFT-395 Python Python library + compiler does not support unicode strings (Unassigned)
-THRIFT-133 Ruby 'namespace ruby' should error out, or be an alias to 'namespace rb' (Bryan Duxbury)
-THRIFT-664 Ruby Ruby extension fails to build with Ruby 1.9.1 (Rajesh Malepati)
-THRIFT-699 Ruby Excise unused "native protocol method table" stuff from thrift_native (Bryan Duxbury)
-THRIFT-767 Ruby ruby compiler does not keep comments for enum values (Bryan Duxbury)
-THRIFT-811 Ruby http_client_transport.rb: allow custom http headers (Tony Kamenick)
-THRIFT-459 Ruby Ruby installation always tries to write to /Library/Ruby/site (Matthieu Imbert)
-
-
-Thrift 0.1.0 - Incubating (not released)
---------------------------------------------------------------------------------
-Compatibility Breaking Changes:
- C++:
- * It's quite possible that regenerating code and rebuilding will be
- required. Make sure your headers match your libs!
-
- Java:
-
- Python:
-
- Ruby:
- * Generated files now have underscored names [THRIFT-421]
- * The library has been rearranged to be more Ruby-like [THRIFT-276]
-
- Erlang:
- * Generated code will have to be regenerated, and the new code will
- have to be deployed atomically with the new library code [THRIFT-136]
-
-New Features and Bug Fixes:
- C++:
- * Support for TCompactProtocol [THRIFT-333]
-
- Java:
- * Support for TCompactProtocol [THRIFT-110]
-
- Python:
- * Support for Twisted [THRIFT-148]
-
- Ruby:
- * Support for TCompactProtocol [THRIFT-332]
-
diff --git a/CHANGES.md b/CHANGES.md
new file mode 100644
index 0000000..df73121
--- /dev/null
+++ b/CHANGES.md
@@ -0,0 +1,2943 @@
+# Apache Thrift Changelog
+
+## 0.13.0
+
+### New Languages
+
+### Deprecated Languages
+
+- [THRIFT-4723](https://issues.apache.org/jira/browse/THRIFT-4723) - CSharp and Netcore targets are deprecated and will be removed with the next release - use NetStd instead.
+
+### Removed Languages
+
+- [THRIFT-4719](https://issues.apache.org/jira/browse/THRIFT-4719) - Cocoa language was removed - use swift instead.
+
+### Breaking Changes
+
+- [THRIFT-4743](https://issues.apache.org/jira/browse/THRIFT-4743) - compiler: removed the plug-in mechanism
+- [THRIFT-4720](https://issues.apache.org/jira/browse/THRIFT-4720) - cpp: C++03/C++98 support has been removed; also removed boost as a runtime dependency
+- [THRIFT-4730](https://issues.apache.org/jira/browse/THRIFT-4730) - cpp: BoostThreadFactory, PosixThreadFactory, StdThreadFactory removed
+- [THRIFT-4732](https://issues.apache.org/jira/browse/THRIFT-4732) - cpp: CMake build changed to use BUILD_SHARED_LIBS
+- [THRIFT-4735](https://issues.apache.org/jira/browse/THRIFT-4735) - cpp: Removed Qt4 support
+- [THRIFT-4740](https://issues.apache.org/jira/browse/THRIFT-4740) - cpp: Use std::chrono::duration for timeouts
+- [THRIFT-4762](https://issues.apache.org/jira/browse/THRIFT-4762) - cpp: TTransport::getOrigin() is now const
+- [THRIFT-4702](https://issues.apache.org/jira/browse/THRIFT-4702) - java: class org.apache.thrift.AutoExpandingBuffer is no longer public
+- [THRIFT-4709](https://issues.apache.org/jira/browse/THRIFT-4709) - java: changes to UTF-8 handling require JDK 1.7 at a minimum
+- [THRIFT-4712](https://issues.apache.org/jira/browse/THRIFT-4712) - java: class org.apache.thrift.ShortStack is no longer public
+- [THRIFT-4725](https://issues.apache.org/jira/browse/THRIFT-4725) - java: change return type signature of 'process' methods
+- [THRIFT-4675](https://issues.apache.org/jira/browse/THRIFT-4675) - js: now uses node-int64 for 64 bit integer constants
+- [THRIFT-4841](https://issues.apache.org/jira/browse/THRIFT-4841) - delphi: old THTTPTransport is now TMsxmlHTTPTransport
+- [THRIFT-4536](https://issues.apache.org/jira/browse/THRIFT-4536) - rust: convert from try-from crate to rust stable (1.34+), re-export ordered-float
+
+### Known Issues (Blocker or Critical)
+
+
+## 0.12.0
+
+Released 2019-JAN-04
+
+### New Languages
+- Common LISP (cl)
+- Swift
+- Typescript (nodets)
+
+### Deprecated Languages
+- C++03/C++98 (move to C++11)
+- Cocoa (move to Swift)
+
+### Breaking Changes (since 0.11.0)
+- [THRIFT-4529](https://issues.apache.org/jira/browse/THRIFT-4529) - Rust enum variants are now camel-cased instead of uppercased to conform to Rust naming conventions
+- [THRIFT-4448](https://issues.apache.org/jira/browse/THRIFT-4448) - Support for golang 1.6 and earlier has been dropped.
+- [THRIFT-4474](https://issues.apache.org/jira/browse/THRIFT-4474) - PHP now uses the PSR-4 loader by default instead of class maps.
+- [THRIFT-4532](https://issues.apache.org/jira/browse/THRIFT-4532) - method signatures changed in the compiler's t_oop_generator.
+- [THRIFT-4648](https://issues.apache.org/jira/browse/THRIFT-4648) - The C (GLib) compiler's handling of namespaces has been improved.
+
+### Known Issues (Blocker or Critical)
+- [THRIFT-4037](https://issues.apache.org/jira/browse/THRIFT-4037) - build: use a single build system for thrift
+- [THRIFT-4119](https://issues.apache.org/jira/browse/THRIFT-4119) - build: bootstrap.sh is missing from source tarball
+- [THRIFT-3289](https://issues.apache.org/jira/browse/THRIFT-3289) - csharp: socket exhaustion in csharp implementation
+- [THRIFT-3029](https://issues.apache.org/jira/browse/THRIFT-3029) - cocoa: Getters for fields defined with uppercase names do not work
+- [THRIFT-3325](https://issues.apache.org/jira/browse/THRIFT-3325) - cocoa: Extended services aren't subclasses in generated Cocoa
+- [THRIFT-4116](https://issues.apache.org/jira/browse/THRIFT-4116) - cocoa: Thrift de-capitalizes the name of IsSet property in Cocoa
+- [THRIFT-3877](https://issues.apache.org/jira/browse/THRIFT-3877) - cpp: the http implementation is not standard; interop with other languages is spotty at best
+- [THRIFT-4180](https://issues.apache.org/jira/browse/THRIFT-4180) - cpp: Impossible to build Thrift C++ library for Android (NDK)
+- [THRIFT-4384](https://issues.apache.org/jira/browse/THRIFT-4384) - cpp: Using multiple async services simultaneously is not thread-safe
+- [THRIFT-3108](https://issues.apache.org/jira/browse/THRIFT-3108) - haskell: Defaulted struct parameters on a service generates invalid Haskell
+- [THRIFT-3990](https://issues.apache.org/jira/browse/THRIFT-3990) - nodejs: Exception swallowed by deserialization function
+- [THRIFT-4214](https://issues.apache.org/jira/browse/THRIFT-4214) - nodejs: map<i64,value> key treated as hex value in JavaScript
+- [THRIFT-4602](https://issues.apache.org/jira/browse/THRIFT-4602) - nodejs: ERROR in ./node_modules/thrift/lib/nodejs/lib/thrift/connection.js Module not found: Error: Can't resolve 'child_process'
+- [THRIFT-4639](https://issues.apache.org/jira/browse/THRIFT-4639) - nodejs: Sequence numbering for multiplexed protocol broken
+- [THRIFT-1310](https://issues.apache.org/jira/browse/THRIFT-1310) - php: sequence and reconnection management issues
+- [THRIFT-1538](https://issues.apache.org/jira/browse/THRIFT-1538) - php: Error during deserialization int64 on 32-bit architecture
+- [THRIFT-1580](https://issues.apache.org/jira/browse/THRIFT-1580) - php: thrift type i64 java to php serialize/deserealize not working
+- [THRIFT-1950](https://issues.apache.org/jira/browse/THRIFT-1950) - php: PHP gets stuck in infinite loop
+- [THRIFT-2954](https://issues.apache.org/jira/browse/THRIFT-2954) - python: sending int or float in a double field breaks the connection
+- [THRIFT-4080](https://issues.apache.org/jira/browse/THRIFT-4080) - python: unix sockets can get stuck forever
+- [THRIFT-4281](https://issues.apache.org/jira/browse/THRIFT-4281) - python: generated code is out of order and causes load issues
+- [THRIFT-4677](https://issues.apache.org/jira/browse/THRIFT-4677) - py3: UnicodeDecideError in Python3
+
+### Build Process
+- [THRIFT-4067](https://issues.apache.org/jira/browse/THRIFT-4067) - Windows thrift compiler distributed on the apache web site has runtime dependencies
+- [THRIFT-4308](https://issues.apache.org/jira/browse/THRIFT-4308) - D language docker images need demios for libevent and openssl fixed to re-enable make cross on dlang
+- [THRIFT-4579](https://issues.apache.org/jira/browse/THRIFT-4579) - Use Ubuntu Bionic (18.04 LTS) for CI builds instead of Artful (17.10)
+- [THRIFT-4508](https://issues.apache.org/jira/browse/THRIFT-4508) - Define CI operating system coverage rules for the project and (hopefully) simplify CI a little more
+- [THRIFT-4397](https://issues.apache.org/jira/browse/THRIFT-4397) - ubuntu install instructions broken on 16.04
+- [THRIFT-4545](https://issues.apache.org/jira/browse/THRIFT-4545) - Appveyor builds are failing due to a haskell / cabal update in chocolatey
+- [THRIFT-4452](https://issues.apache.org/jira/browse/THRIFT-4452) - optimize Dockerfile (only onetime apt-get update)
+- [THRIFT-4440](https://issues.apache.org/jira/browse/THRIFT-4440) - rm `build/docker/ubuntu-trusty/Dockerfile.orig`
+- [THRIFT-4352](https://issues.apache.org/jira/browse/THRIFT-4352) - Ubuntu Artful doesn't appear to be compatible with Thrift and Haxe 3.4.2
+- [THRIFT-4666](https://issues.apache.org/jira/browse/THRIFT-4666) - DLang Client Pool Test fails sporadically
+- [THRIFT-4676](https://issues.apache.org/jira/browse/THRIFT-4676) - CL tutorial build fails sporadically
+- [THRIFT-4456](https://issues.apache.org/jira/browse/THRIFT-4456) - Make haxelib download quiet so it doesn't blow up the build log
+- [THRIFT-4605](https://issues.apache.org/jira/browse/THRIFT-4605) - bootstrap.sh fails if automake=1.16.1
+
+### c_glib
+- [THRIFT-4648](https://issues.apache.org/jira/browse/THRIFT-4648) - The C (GLib) compiler's handling of namespaces has been improved.
+- [THRIFT-4622](https://issues.apache.org/jira/browse/THRIFT-4622) - glibC compilation issue
+- [THRIFT-4671](https://issues.apache.org/jira/browse/THRIFT-4671) - c glib is unable to handle client close unexpectedly
+
+### cl (new language support in 0.12.0)
+- [THRIFT-82](https://issues.apache.org/jira/browse/THRIFT-82) - Common Lisp support
+
+### csharp
+- [THRIFT-4558](https://issues.apache.org/jira/browse/THRIFT-4558) - reserved Csharp keywords are not escaped in some cases
+- [THRIFT-4637](https://issues.apache.org/jira/browse/THRIFT-4637) - C# async mode generates incorrect code with inherited services
+- [THRIFT-4672](https://issues.apache.org/jira/browse/THRIFT-4672) - IAsyncResult style methods not being supported by certain transports leads to issues in mixed ISync/IAsync use cases
+- [THRIFT-4539](https://issues.apache.org/jira/browse/THRIFT-4539) - Allow TBufferedTransport to be used as base class
+- [THRIFT-4535](https://issues.apache.org/jira/browse/THRIFT-4535) - XML docs; code cleanup (tabs->spaces; String->string)
+- [THRIFT-4492](https://issues.apache.org/jira/browse/THRIFT-4492) - protected ExceptionType type member of TApplicationException cannot be accessed
+- [THRIFT-4446](https://issues.apache.org/jira/browse/THRIFT-4446) - JSONProtocol Base64 Encoding Trims Padding
+- [THRIFT-4455](https://issues.apache.org/jira/browse/THRIFT-4455) - Missing dispose calls in ThreadedServer & ThreadpoolServer
+- [THRIFT-4609](https://issues.apache.org/jira/browse/THRIFT-4609) - keep InnerException wherever appropriate
+- [THRIFT-4673](https://issues.apache.org/jira/browse/THRIFT-4673) - IAsyncResult not supported by layered transports (buffered/framed)
+
+### cpp
+- [THRIFT-4476](https://issues.apache.org/jira/browse/THRIFT-4476) - Typecasting problem on list items
+- [THRIFT-4465](https://issues.apache.org/jira/browse/THRIFT-4465) - TNonblockingServer throwing THRIFT LOGGER: TConnection::workSocket(): THRIFT_EAGAIN (unavailable resources)
+- [THRIFT-4680](https://issues.apache.org/jira/browse/THRIFT-4680) - TBufferTransports.h does not compile under Visual Studio 2017
+- [THRIFT-4618](https://issues.apache.org/jira/browse/THRIFT-4618) - TNonblockingServer crash because of limitation of select()
+- [THRIFT-4620](https://issues.apache.org/jira/browse/THRIFT-4620) - TZlibTransport.cpp doesn't ensure that there is enough space for the zlib flush marker in the buffer.
+- [THRIFT-4571](https://issues.apache.org/jira/browse/THRIFT-4571) - ZeroMQ contrib library needs a refresh
+- [THRIFT-4559](https://issues.apache.org/jira/browse/THRIFT-4559) - TSSLServerSocket incorrectly prints errors
+- [THRIFT-4578](https://issues.apache.org/jira/browse/THRIFT-4578) - Move `TAsyncProtocolProcessor` into main thrift library
+- [THRIFT-4418](https://issues.apache.org/jira/browse/THRIFT-4418) - evhttp_connection_new is deprecated; use evhttp_connection_base_new
+
+### compiler
+- [THRIFT-4644](https://issues.apache.org/jira/browse/THRIFT-4644) - Compiler cannot be compiled on macOS(maybe also on other platforms with clang)
+- [THRIFT-4531](https://issues.apache.org/jira/browse/THRIFT-4531) - Thrift generates wrong Python code for immutable structures with optional members
+- [THRIFT-4513](https://issues.apache.org/jira/browse/THRIFT-4513) - thrift generated code is not stable for constants
+- [THRIFT-4532](https://issues.apache.org/jira/browse/THRIFT-4532) - Avoid updating Thrift compiler generated code if the output has not changed
+- [THRIFT-4400](https://issues.apache.org/jira/browse/THRIFT-4400) - Visual Studio Compiler project should link runtime statically in release builds
+- [THRIFT-4399](https://issues.apache.org/jira/browse/THRIFT-4399) - plugin.thrift t_const_value is not used as a union in C++ code -- fix this
+- [THRIFT-4496](https://issues.apache.org/jira/browse/THRIFT-4496) - Dealing with language keywords in Thrift (e.g. service method names)
+- [THRIFT-4393](https://issues.apache.org/jira/browse/THRIFT-4393) - repeated runs of compiler produce different binary output at plugin interface
+
+### dlang
+- [THRIFT-4478](https://issues.apache.org/jira/browse/THRIFT-4478) - Thrift will not build with dlang 2.078 or later
+- [THRIFT-4503](https://issues.apache.org/jira/browse/THRIFT-4503) - dlang servers logError on normal client disconnection
+- [THRIFT-4308](https://issues.apache.org/jira/browse/THRIFT-4308) - D language docker images need demios for libevent and openssl fixed to re-enable make cross on dlang
+
+### dart
+- [THRIFT-4646](https://issues.apache.org/jira/browse/THRIFT-4646) - Effective Dart and Exceptions
+- [THRIFT-4439](https://issues.apache.org/jira/browse/THRIFT-4439) - Shouldn't download dart.deb directly.
+
+### delphi
+- [THRIFT-4562](https://issues.apache.org/jira/browse/THRIFT-4562) - Calling wrong exception CTOR leads to "call failed: unknown result" instead of the real exception being thrown
+- [THRIFT-4554](https://issues.apache.org/jira/browse/THRIFT-4554) - uncompileable code with member names that are also types under specific conditions
+- [THRIFT-4422](https://issues.apache.org/jira/browse/THRIFT-4422) - Add Async implementation via IFuture
+- [THRIFT-4485](https://issues.apache.org/jira/browse/THRIFT-4485) - Possible invalid ptr AV with overlapped read/write on pipes
+- [THRIFT-4549](https://issues.apache.org/jira/browse/THRIFT-4549) - Thrift exceptions should derive from TException
+- [THRIFT-4540](https://issues.apache.org/jira/browse/THRIFT-4540) - buffered transport broken when trying to re-open a formerly closed transport
+- [THRIFT-4473](https://issues.apache.org/jira/browse/THRIFT-4473) - Move Thrift.Console.pas out of the Library
+- [THRIFT-4490](https://issues.apache.org/jira/browse/THRIFT-4490) - Allow a default service as fallback for multiplex processors connected by old clients
+- [THRIFT-4454](https://issues.apache.org/jira/browse/THRIFT-4454) - Large writes/reads may cause range check errors in debug mode
+- [THRIFT-4461](https://issues.apache.org/jira/browse/THRIFT-4461) - Compiler directive should match Delphi XE4
+- [THRIFT-4462](https://issues.apache.org/jira/browse/THRIFT-4462) - First line in Console duplicated
+- [THRIFT-4642](https://issues.apache.org/jira/browse/THRIFT-4642) - FPU ctrl word settings may cause an unexpected "denormalized" error
+- [THRIFT-4589](https://issues.apache.org/jira/browse/THRIFT-4589) - HTTP client timeouts are a) incomplete and b) not used at all
+- [THRIFT-4590](https://issues.apache.org/jira/browse/THRIFT-4590) - running the test client using HTTP transport leads to "CoInitialize not called"
+
+### erlang
+- [THRIFT-4497](https://issues.apache.org/jira/browse/THRIFT-4497) - Erlang records should use map() for map type
+- [THRIFT-4495](https://issues.apache.org/jira/browse/THRIFT-4495) - Erlang records should allow 'undefined' for non-required fields
+- [THRIFT-4580](https://issues.apache.org/jira/browse/THRIFT-4580) - Fix erlang tutorial unpack on Windows
+- [THRIFT-4582](https://issues.apache.org/jira/browse/THRIFT-4582) - Ubuntu Xenial erlang 18.3 "make check" fails
+
+### golang
+- [THRIFT-4448](https://issues.apache.org/jira/browse/THRIFT-4448) - Support for golang 1.6 and earlier has been dropped.
+- [THRIFT-4253](https://issues.apache.org/jira/browse/THRIFT-4253) - Go generator assigns strings to field in const instead of pointers.
+- [THRIFT-4573](https://issues.apache.org/jira/browse/THRIFT-4573) - Unions Field Count Does Not Consider Binary
+- [THRIFT-4447](https://issues.apache.org/jira/browse/THRIFT-4447) - Golang: Panic on p.c.Call when using deprecated initializers
+- [THRIFT-4650](https://issues.apache.org/jira/browse/THRIFT-4650) - Required field incorrectly marked as set when fieldType does not match
+- [THRIFT-4486](https://issues.apache.org/jira/browse/THRIFT-4486) - Golang: -remote.go client cleanup
+- [THRIFT-4537](https://issues.apache.org/jira/browse/THRIFT-4537) - TSimpleServer can exit Accept loop with lock still acquired
+- [THRIFT-4516](https://issues.apache.org/jira/browse/THRIFT-4516) - Add support for go 1.10
+- [THRIFT-4421](https://issues.apache.org/jira/browse/THRIFT-4421) - golang tests rely on gomock, which has change behaviour, causing tests to fail
+- [THRIFT-4626](https://issues.apache.org/jira/browse/THRIFT-4626) - Communication crash when using binary/compact protocol and zlib transport
+- [THRIFT-4659](https://issues.apache.org/jira/browse/THRIFT-4659) - golang race detected when closing listener socket
+
+### haskell
+- [THRIFT-4634](https://issues.apache.org/jira/browse/THRIFT-4634) - Haskell builds with older cabal cannot reconcile complex version requirements
+
+### java
+- [THRIFT-4259](https://issues.apache.org/jira/browse/THRIFT-4259) - Thrift does not compile due to Ant Maven task errors
+- [THRIFT-1418](https://issues.apache.org/jira/browse/THRIFT-1418) - Compiling Thrift from source: Class org.apache.tools.ant.taskdefs.ConditionTask doesn't support the nested "typefound" element
+- [THRIFT-4530](https://issues.apache.org/jira/browse/THRIFT-4530) - proposal: add nullability annotations to generated Java code
+- [THRIFT-4614](https://issues.apache.org/jira/browse/THRIFT-4614) - Generate missing @Nullable annotations for Java iterator getters
+- [THRIFT-4555](https://issues.apache.org/jira/browse/THRIFT-4555) - Getter of binary field in Java creates unnecessary copy
+- [THRIFT-3983](https://issues.apache.org/jira/browse/THRIFT-3983) - libthrift is deployed on central with pom packaging instead of jar
+- [THRIFT-4294](https://issues.apache.org/jira/browse/THRIFT-4294) - Java Configure Fails for Ant >= 1.10
+- [THRIFT-4178](https://issues.apache.org/jira/browse/THRIFT-4178) - Java libraries missing from package when using cmake
+- [THRIFT-4120](https://issues.apache.org/jira/browse/THRIFT-4120) - pom files are not generated or provided in the build
+- [THRIFT-1507](https://issues.apache.org/jira/browse/THRIFT-1507) - Maven can't download resource from central when behind a proxy and won't use local repository
+- [THRIFT-4556](https://issues.apache.org/jira/browse/THRIFT-4556) - Optional rethrow of unhandled exceptions in java processor
+- [THRIFT-4337](https://issues.apache.org/jira/browse/THRIFT-4337) - Able to set keyStore and trustStore as InputStream in the TSSLTransportFactory.TSSLTransportParameters
+- [THRIFT-4566](https://issues.apache.org/jira/browse/THRIFT-4566) - Pass message of unhandled exception to optional rethrow.
+- [THRIFT-4506](https://issues.apache.org/jira/browse/THRIFT-4506) - Remove assertion in Java SASL code that would be ignored in release builds
+- [THRIFT-4470](https://issues.apache.org/jira/browse/THRIFT-4470) - Include popular IDE file templates to gitignore
+- [THRIFT-4429](https://issues.apache.org/jira/browse/THRIFT-4429) - Make TThreadPoolServer.executorService_ available in inherited classes and refactor methods to be able customization
+- [THRIFT-3769](https://issues.apache.org/jira/browse/THRIFT-3769) - Fix logic of THRIFT-2268
+- [THRIFT-4494](https://issues.apache.org/jira/browse/THRIFT-4494) - Increase Java Socket Buffer Size
+- [THRIFT-4499](https://issues.apache.org/jira/browse/THRIFT-4499) - Remove Magic Number In TFIleTransport
+
+### js
+- [THRIFT-4406](https://issues.apache.org/jira/browse/THRIFT-4406) - JavaScript: Use modern Promise implementations
+- [THRIFT-4625](https://issues.apache.org/jira/browse/THRIFT-4625) - let / const variable decorators for es6 compiler
+- [THRIFT-4653](https://issues.apache.org/jira/browse/THRIFT-4653) - ES6 Classes
+- [THRIFT-4592](https://issues.apache.org/jira/browse/THRIFT-4592) - JS: readI32 performance on large arrays is very poor in Chrome
+- [THRIFT-4509](https://issues.apache.org/jira/browse/THRIFT-4509) - js and nodejs libraries need to be refreshed with current libraries
+- [THRIFT-4403](https://issues.apache.org/jira/browse/THRIFT-4403) - thrift.js: Incorrect usage of 'this' in TWebSocketTransport.__onOpen
+- [THRIFT-4436](https://issues.apache.org/jira/browse/THRIFT-4436) - Deserialization of nested list discards content
+- [THRIFT-4437](https://issues.apache.org/jira/browse/THRIFT-4437) - JS WebSocket client callbacks invoked twice on parallel requests
+- [THRIFT-4679](https://issues.apache.org/jira/browse/THRIFT-4679) - Duplicate declaration of InputBufferUnderrunError in lib/nodejs/lib/thrift/json_protocol.js
+- [THRIFT-4551](https://issues.apache.org/jira/browse/THRIFT-4551) - Add prettier for consistent JS code formatting
+
+### lua
+- [THRIFT-4591](https://issues.apache.org/jira/browse/THRIFT-4591) - lua client uses two write() calls per framed message send
+- [THRIFT-3863](https://issues.apache.org/jira/browse/THRIFT-3863) - Can't "make install" Lua Library
+
+### netcore
+- [THRIFT-4524](https://issues.apache.org/jira/browse/THRIFT-4524) - .NET Core Server doesn't close properly when cancelled
+- [THRIFT-4434](https://issues.apache.org/jira/browse/THRIFT-4434) - Update .NET Core components, add tests for .Net Core library and .Net Core compiler, fix bugs and build process
+- [THRIFT-4446](https://issues.apache.org/jira/browse/THRIFT-4446) - JSONProtocol Base64 Encoding Trims Padding
+
+### node.js
+- [THRIFT-4225](https://issues.apache.org/jira/browse/THRIFT-4225) - Error handling malformed arguments leaks memory, corrupts transport buffers causing next RPC to fail
+- [THRIFT-3950](https://issues.apache.org/jira/browse/THRIFT-3950) - Memory leak while calling oneway method
+- [THRIFT-3143](https://issues.apache.org/jira/browse/THRIFT-3143) - add typescript directory support
+- [THRIFT-4564](https://issues.apache.org/jira/browse/THRIFT-4564) - TBufferedTransport can leave corrupt data in the buffer
+- [THRIFT-4647](https://issues.apache.org/jira/browse/THRIFT-4647) - Node.js Fileserver webroot path
+- [THRIFT-4489](https://issues.apache.org/jira/browse/THRIFT-4489) - Unix domain socket support for NodeJS client
+- [THRIFT-4443](https://issues.apache.org/jira/browse/THRIFT-4443) - node.js json_protocol throws error in skip function
+- [THRIFT-4604](https://issues.apache.org/jira/browse/THRIFT-4604) - NodeJS: Expose Int64 from browser.js for consumption by browser
+- [THRIFT-4480](https://issues.apache.org/jira/browse/THRIFT-4480) - NodeJS warning on binary_protocol writeMessageEnd when seqid = 0
+
+### perl
+- [THRIFT-4382](https://issues.apache.org/jira/browse/THRIFT-4382) - Replace the use of Perl Indirect Object Syntax calls to new()
+- [THRIFT-4471](https://issues.apache.org/jira/browse/THRIFT-4471) - Thrift CPAN release is missing Makefile.PL and the clients are unable to build the module
+- [THRIFT-4416](https://issues.apache.org/jira/browse/THRIFT-4416) - Perl CPAN Packaging Improvements
+
+### php
+- [THRIFT-4474](https://issues.apache.org/jira/browse/THRIFT-4474) - PHP generator use PSR-4 default
+- [THRIFT-4463](https://issues.apache.org/jira/browse/THRIFT-4463) - PHP generated code match PSR-2
+- [THRIFT-4373](https://issues.apache.org/jira/browse/THRIFT-4373) - Extending Thrift class results in "Attempt serialize from non-Thrift object"
+- [THRIFT-4354](https://issues.apache.org/jira/browse/THRIFT-4354) - TSocket block on read
+- [THRIFT-4423](https://issues.apache.org/jira/browse/THRIFT-4423) - migrate php library to psr-4
+- [THRIFT-4656](https://issues.apache.org/jira/browse/THRIFT-4656) - infinite loop in latest PHP library
+- [THRIFT-4477](https://issues.apache.org/jira/browse/THRIFT-4477) - TBufferedTransport must have underlying transport
+- [THRIFT-4475](https://issues.apache.org/jira/browse/THRIFT-4475) - lib/php/test should be checked for PSR-2
+- [THRIFT-4498](https://issues.apache.org/jira/browse/THRIFT-4498) - add phpcs back
+- [THRIFT-4460](https://issues.apache.org/jira/browse/THRIFT-4460) - php library use PSR-2
+- [THRIFT-4641](https://issues.apache.org/jira/browse/THRIFT-4641) - TCurlClient doesn't check for HTTP status code
+- [THRIFT-4645](https://issues.apache.org/jira/browse/THRIFT-4645) - TCurlClient: show actual error message when throwing TTransportException
+- [THRIFT-4674](https://issues.apache.org/jira/browse/THRIFT-4674) - Add stream context support into PHP/THttpClient
+- [THRIFT-4459](https://issues.apache.org/jira/browse/THRIFT-4459) - reduce php library directory depth
+
+### python
+- [THRIFT-4670](https://issues.apache.org/jira/browse/THRIFT-4670) - Twisted, slots, and void method fails with "object has no attribute 'success'"
+- [THRIFT-4464](https://issues.apache.org/jira/browse/THRIFT-4464) - Potentially server-crashing typo in Python TNonblockingServer
+- [THRIFT-4548](https://issues.apache.org/jira/browse/THRIFT-4548) - Supporting TBinaryProtocolAccelerated protocol when using TMultiplexedProcessor in Python
+- [THRIFT-4577](https://issues.apache.org/jira/browse/THRIFT-4577) - Outdated cipher string in python unit test
+- [THRIFT-4505](https://issues.apache.org/jira/browse/THRIFT-4505) - python build on Vagrant Windows boxes fails
+- [THRIFT-4621](https://issues.apache.org/jira/browse/THRIFT-4621) - THeader for Python
+- [THRIFT-4668](https://issues.apache.org/jira/browse/THRIFT-4668) - make socket backlog configurable for python
+- [THRIFT-4561](https://issues.apache.org/jira/browse/THRIFT-4561) - Python: cleanup socket timeout settings
+
+### ruby
+- [THRIFT-4289](https://issues.apache.org/jira/browse/THRIFT-4289) - Thrift RSpec test suite fails with Ruby 2.4.x due to Fixnum deprecation
+- [THRIFT-4342](https://issues.apache.org/jira/browse/THRIFT-4342) - Support ruby rspec 3
+- [THRIFT-4525](https://issues.apache.org/jira/browse/THRIFT-4525) - Add ssl socket option to ruby cross tests
+- [THRIFT-4450](https://issues.apache.org/jira/browse/THRIFT-4450) - Add seek support to TCompactInputProtocol in Rust
+- [THRIFT-4631](https://issues.apache.org/jira/browse/THRIFT-4631) - Codegen Creates Invalid Ruby for Recursive Structs
+- [THRIFT-4472](https://issues.apache.org/jira/browse/THRIFT-4472) - Fix the genspec for ruby so it does not complain about an invalid license
+
+### rust
+- [THRIFT-4662](https://issues.apache.org/jira/browse/THRIFT-4662) - Rust const string calls function at compile time
+- [THRIFT-4661](https://issues.apache.org/jira/browse/THRIFT-4661) - Rust enum name wrong case in generated structs
+- [THRIFT-4617](https://issues.apache.org/jira/browse/THRIFT-4617) - Avoid generating conflicting struct names in Rust code
+- [THRIFT-4529](https://issues.apache.org/jira/browse/THRIFT-4529) - Rust generation should include #![allow(non_snake_case)] or force conform to Rust style guidelines
+- [THRIFT-4390](https://issues.apache.org/jira/browse/THRIFT-4390) - Rust binary protocol and buffered transport cannot handle writes above 4096 bytes
+- [THRIFT-4419](https://issues.apache.org/jira/browse/THRIFT-4419) - Rust framed transport cannot handle writes above 4096 bytes
+- [THRIFT-4658](https://issues.apache.org/jira/browse/THRIFT-4658) - Rust's TBinaryInputProtocol fails when strict is false
+- [THRIFT-4187](https://issues.apache.org/jira/browse/THRIFT-4187) - Dart -> Rust Framed cross tests fail
+- [THRIFT-4664](https://issues.apache.org/jira/browse/THRIFT-4664) - Rust cannot create ReadHalf/WriteHalf to implement custom tranports
+- [THRIFT-4665](https://issues.apache.org/jira/browse/THRIFT-4665) - Keep Rust library up-to-date on crates.io
+
+### swift (new language support in 0.12.0)
+- [THRIFT-3773](https://issues.apache.org/jira/browse/THRIFT-3773) - Swift Library
+
+### test suite
+- [THRIFT-4515](https://issues.apache.org/jira/browse/THRIFT-4515) - Gracefully shutdown cross-test servers to fully test teardown
+- [THRIFT-4085](https://issues.apache.org/jira/browse/THRIFT-4085) - Add .NET Core to the make cross standard test suite
+- [THRIFT-4358](https://issues.apache.org/jira/browse/THRIFT-4358) - Add unix domain sockets in ruby to cross test - code exists
+
+### typescript (new language support in 0.12.0)
+- [THRIFT-3143](https://issues.apache.org/jira/browse/THRIFT-3143) - add typescript directory support
+
+## 0.11.0
+
+Released 2017-DEC-27
+
+### Sub-task
+- [THRIFT-2733](https://issues.apache.org/jira/browse/THRIFT-2733) - Erlang coding standards
+- [THRIFT-2740](https://issues.apache.org/jira/browse/THRIFT-2740) - Perl coding standards
+- [THRIFT-3610](https://issues.apache.org/jira/browse/THRIFT-3610) - Streamline exception handling in Python server handler
+- [THRIFT-3686](https://issues.apache.org/jira/browse/THRIFT-3686) - Java processor should report internal error on uncaught exception
+- [THRIFT-4049](https://issues.apache.org/jira/browse/THRIFT-4049) - Skip() should throw TProtocolException.INVALID_DATA on unknown data types
+- [THRIFT-4053](https://issues.apache.org/jira/browse/THRIFT-4053) - Skip() should throw TProtocolException.INVALID_DATA on unknown data types
+- [THRIFT-4136](https://issues.apache.org/jira/browse/THRIFT-4136) - Align is_binary() method with is_string() to simplify those checks
+- [THRIFT-4137](https://issues.apache.org/jira/browse/THRIFT-4137) - Fix remaining undefined behavior invalid vptr casts in Thrift Compiler
+- [THRIFT-4138](https://issues.apache.org/jira/browse/THRIFT-4138) - Fix remaining undefined behavior invalid vptr casts in C++ library
+- [THRIFT-4296](https://issues.apache.org/jira/browse/THRIFT-4296) - Fix Ubuntu Xenial build environment for the python language
+- [THRIFT-4298](https://issues.apache.org/jira/browse/THRIFT-4298) - Fix Ubuntu Xenial build environment for the go 1.6 language
+- [THRIFT-4299](https://issues.apache.org/jira/browse/THRIFT-4299) - Fix Ubuntu Xenial build environment for the D language
+- [THRIFT-4300](https://issues.apache.org/jira/browse/THRIFT-4300) - Fix make cross in Ubuntu Xenial docker environment, once all language support issues are fixed
+- [THRIFT-4302](https://issues.apache.org/jira/browse/THRIFT-4302) - Fix Ubuntu Xenial make cross testing for lua and php7
+- [THRIFT-4398](https://issues.apache.org/jira/browse/THRIFT-4398) - Update EXTRA_DIST for "make dist"
+
+### Bug
+- [THRIFT-381](https://issues.apache.org/jira/browse/THRIFT-381) - Fail fast if configure detects C++ problems
+- [THRIFT-1677](https://issues.apache.org/jira/browse/THRIFT-1677) - MinGW support broken
+- [THRIFT-1805](https://issues.apache.org/jira/browse/THRIFT-1805) - Thrift should not swallow ALL exceptions
+- [THRIFT-2026](https://issues.apache.org/jira/browse/THRIFT-2026) - Fix TCompactProtocol 64 bit builds
+- [THRIFT-2642](https://issues.apache.org/jira/browse/THRIFT-2642) - Recursive structs don't work in python
+- [THRIFT-2889](https://issues.apache.org/jira/browse/THRIFT-2889) - stable release 0.9.2, erlang tutorial broken
+- [THRIFT-2913](https://issues.apache.org/jira/browse/THRIFT-2913) - Ruby Server Thrift::ThreadPoolServer should serve inside a thread
+- [THRIFT-2998](https://issues.apache.org/jira/browse/THRIFT-2998) - Node.js: Missing header from http request
+- [THRIFT-3000](https://issues.apache.org/jira/browse/THRIFT-3000) - .NET implementation has trouble with mixed IP modes
+- [THRIFT-3281](https://issues.apache.org/jira/browse/THRIFT-3281) - Travis CI build passed but the log says BUILD FAILED
+- [THRIFT-3358](https://issues.apache.org/jira/browse/THRIFT-3358) - Makefile:1362: *** missing separator. Stop.
+- [THRIFT-3600](https://issues.apache.org/jira/browse/THRIFT-3600) - Make TTwisted server send exception on unexpected handler error
+- [THRIFT-3602](https://issues.apache.org/jira/browse/THRIFT-3602) - Make Tornado server send exception on unexpected handler error
+- [THRIFT-3657](https://issues.apache.org/jira/browse/THRIFT-3657) - D TFileWriterTransport close should use non-priority send
+- [THRIFT-3700](https://issues.apache.org/jira/browse/THRIFT-3700) - Go Map has wrong default value when optional
+- [THRIFT-3703](https://issues.apache.org/jira/browse/THRIFT-3703) - Unions Field Count Does Not Consider Map/Set/List Fields
+- [THRIFT-3730](https://issues.apache.org/jira/browse/THRIFT-3730) - server log error twice
+- [THRIFT-3778](https://issues.apache.org/jira/browse/THRIFT-3778) - go client can not pass method parameter to server of other language if no field_id is given
+- [THRIFT-3784](https://issues.apache.org/jira/browse/THRIFT-3784) - thrift-maven-plugin generates invalid include directories for IDL in dependency JARs
+- [THRIFT-3801](https://issues.apache.org/jira/browse/THRIFT-3801) - Node Thrift client throws exception with multiplexer and responses that are bigger than a single buffer
+- [THRIFT-3821](https://issues.apache.org/jira/browse/THRIFT-3821) - TMemoryBuffer buffer may overflow when resizing
+- [THRIFT-3832](https://issues.apache.org/jira/browse/THRIFT-3832) - Thrift version 0.9.3 example on Windows, Visual Studio, linking errors during compiling
+- [THRIFT-3847](https://issues.apache.org/jira/browse/THRIFT-3847) - thrift/config.h includes a #define for VERSION which will likely conflict with existing user environment or code
+- [THRIFT-3873](https://issues.apache.org/jira/browse/THRIFT-3873) - Fix various build warnings when using Visual Studio
+- [THRIFT-3891](https://issues.apache.org/jira/browse/THRIFT-3891) - TNonblockingServer configured with more than one IO threads does not always return from serve() upon stop()
+- [THRIFT-3892](https://issues.apache.org/jira/browse/THRIFT-3892) - Thrift uses TLS SNI extension provided by OpenSSL library. Older version of OpenSSL(< 0.9.8f) may create problem because they do not support 'SSL_set_tlsext_host_name()'.
+- [THRIFT-3895](https://issues.apache.org/jira/browse/THRIFT-3895) - Build fails using Java 1.8 with Ant < 1.9
+- [THRIFT-3896](https://issues.apache.org/jira/browse/THRIFT-3896) - map<string,string> data with number string key cannot access that deserialized by php extension
+- [THRIFT-3938](https://issues.apache.org/jira/browse/THRIFT-3938) - Python TNonblockingServer does not work with SSL
+- [THRIFT-3944](https://issues.apache.org/jira/browse/THRIFT-3944) - TSSLSocket has dead code in checkHandshake
+- [THRIFT-3946](https://issues.apache.org/jira/browse/THRIFT-3946) - Java 1.5 compatibility broken for binary fields (java5 option)
+- [THRIFT-3960](https://issues.apache.org/jira/browse/THRIFT-3960) - Inherited services in Lua generator are not named correctly
+- [THRIFT-3962](https://issues.apache.org/jira/browse/THRIFT-3962) - Ant build.xml broken on Windows for Java library
+- [THRIFT-3963](https://issues.apache.org/jira/browse/THRIFT-3963) - Thrift.cabal filename does not match module name
+- [THRIFT-3967](https://issues.apache.org/jira/browse/THRIFT-3967) - gobject/gparam.h:166:33: warning: enumerator value for ‘G_PARAM_DEPRECATED’ is not an integer constant expression
+- [THRIFT-3968](https://issues.apache.org/jira/browse/THRIFT-3968) - Deserializing empty string/binary fields
+- [THRIFT-3974](https://issues.apache.org/jira/browse/THRIFT-3974) - Using clang-3.8 and ThreadSanitizer on the concurrency_test claims bad PThread behavior
+- [THRIFT-3984](https://issues.apache.org/jira/browse/THRIFT-3984) - PHP7 extension causes segfault
+- [THRIFT-4008](https://issues.apache.org/jira/browse/THRIFT-4008) - broken ci due to upstream dependency versioning break
+- [THRIFT-4009](https://issues.apache.org/jira/browse/THRIFT-4009) - Use @implementer instead of implements in TTwisted.py
+- [THRIFT-4010](https://issues.apache.org/jira/browse/THRIFT-4010) - Q.fcall messing up with *this* pointer inside called function
+- [THRIFT-4011](https://issues.apache.org/jira/browse/THRIFT-4011) - Sets of Thrift structs generate Go code that can't be serialized to JSON
+- [THRIFT-4012](https://issues.apache.org/jira/browse/THRIFT-4012) - Python Twisted implementation uses implements, not compatible with Py3
+- [THRIFT-4014](https://issues.apache.org/jira/browse/THRIFT-4014) - align C# meta data in AssemblyInfo.cs
+- [THRIFT-4015](https://issues.apache.org/jira/browse/THRIFT-4015) - Fix wrongly spelled "Thirft"s
+- [THRIFT-4016](https://issues.apache.org/jira/browse/THRIFT-4016) - testInsanity() impl does not conform to test spec in ThriftTest.thrift
+- [THRIFT-4023](https://issues.apache.org/jira/browse/THRIFT-4023) - Skip unexpected field types on read/write
+- [THRIFT-4024](https://issues.apache.org/jira/browse/THRIFT-4024) - Skip() should throw on unknown data types
+- [THRIFT-4026](https://issues.apache.org/jira/browse/THRIFT-4026) - TSSLSocket doesn't work with Python < 2.7.9
+- [THRIFT-4029](https://issues.apache.org/jira/browse/THRIFT-4029) - Accelerated protocols do not build from thrift-py 0.10.0 on PyPI
+- [THRIFT-4031](https://issues.apache.org/jira/browse/THRIFT-4031) - Go plugin generates invalid code for lists of typedef'ed built-in types
+- [THRIFT-4033](https://issues.apache.org/jira/browse/THRIFT-4033) - Default build WITH_PLUGIN=ON for all builds results in packaging errors
+- [THRIFT-4034](https://issues.apache.org/jira/browse/THRIFT-4034) - CMake doesn't work to build compiler on MacOS
+- [THRIFT-4036](https://issues.apache.org/jira/browse/THRIFT-4036) - Add .NET Core environment/build support to the docker image
+- [THRIFT-4038](https://issues.apache.org/jira/browse/THRIFT-4038) - socket check: checking an unsigned number against >= 0 never fails
+- [THRIFT-4042](https://issues.apache.org/jira/browse/THRIFT-4042) - ExtractionError when using accelerated thrift in a multiprocess test
+- [THRIFT-4043](https://issues.apache.org/jira/browse/THRIFT-4043) - thrift perl debian package is placing files in the wrong place
+- [THRIFT-4044](https://issues.apache.org/jira/browse/THRIFT-4044) - Build job 17 failing on every pull request; hspec core (haskell) 2.4 issue
+- [THRIFT-4046](https://issues.apache.org/jira/browse/THRIFT-4046) - MinGW with gcc 6.2 does not compile on Windows
+- [THRIFT-4060](https://issues.apache.org/jira/browse/THRIFT-4060) - Thrift printTo ostream overload mechanism breaks down when types are nested
+- [THRIFT-4062](https://issues.apache.org/jira/browse/THRIFT-4062) - Remove debug print from TServiceClient
+- [THRIFT-4065](https://issues.apache.org/jira/browse/THRIFT-4065) - Document Perl ForkingServer signal restriction imposed by THRIFT-3848 and remove unnecessary code
+- [THRIFT-4068](https://issues.apache.org/jira/browse/THRIFT-4068) - A code comment in Java ServerSocket is wrong around accept()
+- [THRIFT-4073](https://issues.apache.org/jira/browse/THRIFT-4073) - enum files are still being generated with unused imports
+- [THRIFT-4076](https://issues.apache.org/jira/browse/THRIFT-4076) - Appveyor builds failing because ant 1.9.8 was removed from apache servers
+- [THRIFT-4077](https://issues.apache.org/jira/browse/THRIFT-4077) - AI_ADDRCONFIG redefined after recent change to PlatformSocket header
+- [THRIFT-4079](https://issues.apache.org/jira/browse/THRIFT-4079) - Generated perl code that returns structures from included thrift files is missing a necessary use clause
+- [THRIFT-4087](https://issues.apache.org/jira/browse/THRIFT-4087) - Spurious exception destroying TThreadedServer because of incorrect join() call
+- [THRIFT-4102](https://issues.apache.org/jira/browse/THRIFT-4102) - TBufferedTransport performance issue since 0.10.0
+- [THRIFT-4106](https://issues.apache.org/jira/browse/THRIFT-4106) - concurrency_test fails randomly
+- [THRIFT-4108](https://issues.apache.org/jira/browse/THRIFT-4108) - c_glib thrift ssl has multiple bugs and deprecated functions
+- [THRIFT-4109](https://issues.apache.org/jira/browse/THRIFT-4109) - Configure Script uses string comparison for versions
+- [THRIFT-4129](https://issues.apache.org/jira/browse/THRIFT-4129) - C++ TNonblockingServer fd leak when failing to dispatch new connections
+- [THRIFT-4131](https://issues.apache.org/jira/browse/THRIFT-4131) - Javascript with WebSocket handles oneway methods wrong
+- [THRIFT-4134](https://issues.apache.org/jira/browse/THRIFT-4134) - Fix remaining undefined behavior invalid vptr casts
+- [THRIFT-4140](https://issues.apache.org/jira/browse/THRIFT-4140) - Use of non-thread-safe function gmtime()
+- [THRIFT-4141](https://issues.apache.org/jira/browse/THRIFT-4141) - Installation of haxe in docker files refers to a redirect link and fails
+- [THRIFT-4147](https://issues.apache.org/jira/browse/THRIFT-4147) - Rust: protocol should accept transports with non-static lifetime
+- [THRIFT-4148](https://issues.apache.org/jira/browse/THRIFT-4148) - [maven-thrift-plugin] compile error while import a thrift in dependency jar file.
+- [THRIFT-4149](https://issues.apache.org/jira/browse/THRIFT-4149) - System.out pollutes log files
+- [THRIFT-4154](https://issues.apache.org/jira/browse/THRIFT-4154) - PHP close() of a TSocket needs to close any type of socket
+- [THRIFT-4158](https://issues.apache.org/jira/browse/THRIFT-4158) - minor issue in README-MSYS2.md
+- [THRIFT-4159](https://issues.apache.org/jira/browse/THRIFT-4159) - Building tests fails on MSYS2 (MinGW64) due to a (small?) linker error
+- [THRIFT-4160](https://issues.apache.org/jira/browse/THRIFT-4160) - TNonblocking server fix use of closed/freed connections
+- [THRIFT-4161](https://issues.apache.org/jira/browse/THRIFT-4161) - TNonBlocking server using uninitialized event in error paths
+- [THRIFT-4162](https://issues.apache.org/jira/browse/THRIFT-4162) - TNonBlocking handling of TSockets in error state is incorrect after fd is closed
+- [THRIFT-4164](https://issues.apache.org/jira/browse/THRIFT-4164) - Core in TSSLSocket cleanupOpenSSL when destroying a mutex used by openssl
+- [THRIFT-4165](https://issues.apache.org/jira/browse/THRIFT-4165) - C++ build has many warnings under c++03 due to recent changes, cmake needs better platform-independent language level control
+- [THRIFT-4166](https://issues.apache.org/jira/browse/THRIFT-4166) - Recent fix to remove boost::lexical_cast usage broke VS2010
+- [THRIFT-4167](https://issues.apache.org/jira/browse/THRIFT-4167) - Missing compile flag
+- [THRIFT-4170](https://issues.apache.org/jira/browse/THRIFT-4170) - Support lua 5.1 or earlier properly for object length determination
+- [THRIFT-4172](https://issues.apache.org/jira/browse/THRIFT-4172) - node.js tutorial client does not import assert, connection issues are not handled properly
+- [THRIFT-4177](https://issues.apache.org/jira/browse/THRIFT-4177) - Java compiler produces deep copy constructor that could make shallow copy instead
+- [THRIFT-4184](https://issues.apache.org/jira/browse/THRIFT-4184) - Building on Appveyor: invalid escape sequence \L
+- [THRIFT-4185](https://issues.apache.org/jira/browse/THRIFT-4185) - fb303 counter encoding fix
+- [THRIFT-4189](https://issues.apache.org/jira/browse/THRIFT-4189) - Framed/buffered transport Dispose() does not dispose the nested transport
+- [THRIFT-4193](https://issues.apache.org/jira/browse/THRIFT-4193) - Lower the default maxReadBufferBytes for non-blocking servers
+- [THRIFT-4195](https://issues.apache.org/jira/browse/THRIFT-4195) - Compilation to GO produces broken code
+- [THRIFT-4196](https://issues.apache.org/jira/browse/THRIFT-4196) - Cannot generate recursive Rust types
+- [THRIFT-4204](https://issues.apache.org/jira/browse/THRIFT-4204) - typo in compact spec
+- [THRIFT-4206](https://issues.apache.org/jira/browse/THRIFT-4206) - Strings in container fields are not decoded properly with py:dynamic and py:utf8strings
+- [THRIFT-4208](https://issues.apache.org/jira/browse/THRIFT-4208) - C# NamedPipesServer not really working in some scenarios
+- [THRIFT-4211](https://issues.apache.org/jira/browse/THRIFT-4211) - Fix GError glib management under Thrift
+- [THRIFT-4212](https://issues.apache.org/jira/browse/THRIFT-4212) - c_glib flush tries to close SSL even if socket is invalid
+- [THRIFT-4213](https://issues.apache.org/jira/browse/THRIFT-4213) - Travis build fails at curl -sSL https://www.npmjs.com/install.sh | sh
+- [THRIFT-4215](https://issues.apache.org/jira/browse/THRIFT-4215) - Golang TTransportFactory Pattern Squelches Errors
+- [THRIFT-4216](https://issues.apache.org/jira/browse/THRIFT-4216) - Golang Http Clients Do Not Respect User Options
+- [THRIFT-4218](https://issues.apache.org/jira/browse/THRIFT-4218) - Set TCP_NODELAY for PHP client socket
+- [THRIFT-4219](https://issues.apache.org/jira/browse/THRIFT-4219) - Golang HTTP clients created with Nil buffer
+- [THRIFT-4231](https://issues.apache.org/jira/browse/THRIFT-4231) - TJSONProtocol throws unexpected non-Thrift-exception on null strings
+- [THRIFT-4232](https://issues.apache.org/jira/browse/THRIFT-4232) - ./configure does bad ant version check
+- [THRIFT-4234](https://issues.apache.org/jira/browse/THRIFT-4234) - Travis build fails cross language tests with "Unsupported security protocol type"
+- [THRIFT-4237](https://issues.apache.org/jira/browse/THRIFT-4237) - Go TServerSocket Race Conditions
+- [THRIFT-4240](https://issues.apache.org/jira/browse/THRIFT-4240) - Go TSimpleServer does not close properly
+- [THRIFT-4243](https://issues.apache.org/jira/browse/THRIFT-4243) - Go TSimpleServer race on wait in Stop() method
+- [THRIFT-4245](https://issues.apache.org/jira/browse/THRIFT-4245) - Golang TFramedTransport's writeBuffer increases if writes to transport failed
+- [THRIFT-4246](https://issues.apache.org/jira/browse/THRIFT-4246) - Sequence number mismatch on multiplexed clients
+- [THRIFT-4247](https://issues.apache.org/jira/browse/THRIFT-4247) - Compile fails with openssl 1.1
+- [THRIFT-4248](https://issues.apache.org/jira/browse/THRIFT-4248) - Compile fails - strncpy, memcmp, memset not declared in src/thrift/transport/TSSLSocket.cpp
+- [THRIFT-4251](https://issues.apache.org/jira/browse/THRIFT-4251) - Java Epoll Selector Bug
+- [THRIFT-4257](https://issues.apache.org/jira/browse/THRIFT-4257) - Typescript async callbacks do not provide the correct types
+- [THRIFT-4258](https://issues.apache.org/jira/browse/THRIFT-4258) - Boost/std thread wrapping faultiness
+- [THRIFT-4260](https://issues.apache.org/jira/browse/THRIFT-4260) - Go context generation issue. Context is parameter in Interface not in implementation
+- [THRIFT-4261](https://issues.apache.org/jira/browse/THRIFT-4261) - Go context generation issue: breaking change in generated code regarding thrift.TProcessorFunction interface
+- [THRIFT-4262](https://issues.apache.org/jira/browse/THRIFT-4262) - Invalid binding to InterlockedCompareExchange64() with 64-bit targets
+- [THRIFT-4263](https://issues.apache.org/jira/browse/THRIFT-4263) - Fix use after free bug for thrown exceptions
+- [THRIFT-4266](https://issues.apache.org/jira/browse/THRIFT-4266) - Erlang library throws during skipping fields of composite type (maps, lists, structs, sets)
+- [THRIFT-4268](https://issues.apache.org/jira/browse/THRIFT-4268) - Erlang library emits debugging output in transport layer
+- [THRIFT-4273](https://issues.apache.org/jira/browse/THRIFT-4273) - erlang:now/0: Deprecated BIF.
+- [THRIFT-4274](https://issues.apache.org/jira/browse/THRIFT-4274) - Python feature tests for SSL/TLS failing
+- [THRIFT-4279](https://issues.apache.org/jira/browse/THRIFT-4279) - Wrong path in include directive in generated Thrift sources
+- [THRIFT-4283](https://issues.apache.org/jira/browse/THRIFT-4283) - TNamedPipeServer race condition in interrupt
+- [THRIFT-4284](https://issues.apache.org/jira/browse/THRIFT-4284) - File contains a NBSP: lib/nodejs/lib/thrift/web_server.js
+- [THRIFT-4290](https://issues.apache.org/jira/browse/THRIFT-4290) - C# nullable option generates invalid code for non-required enum field with default value
+- [THRIFT-4292](https://issues.apache.org/jira/browse/THRIFT-4292) - TimerManager::remove() is not implemented
+- [THRIFT-4307](https://issues.apache.org/jira/browse/THRIFT-4307) - Make ssl-open timeout effective in golang client
+- [THRIFT-4312](https://issues.apache.org/jira/browse/THRIFT-4312) - Erlang client cannot connect to Python server: exception error: econnrefused
+- [THRIFT-4313](https://issues.apache.org/jira/browse/THRIFT-4313) - Program code of the Erlang tutorial files contain syntax errors
+- [THRIFT-4316](https://issues.apache.org/jira/browse/THRIFT-4316) - TByteBuffer.java will read too much data if a previous read returns fewer bytes than requested
+- [THRIFT-4319](https://issues.apache.org/jira/browse/THRIFT-4319) - command line switch for "evhttp" incorrectly resolved to anon pipes
+- [THRIFT-4323](https://issues.apache.org/jira/browse/THRIFT-4323) - range check errors or NPE in edge cases
+- [THRIFT-4324](https://issues.apache.org/jira/browse/THRIFT-4324) - field names can conflict with local vars in generated code
+- [THRIFT-4328](https://issues.apache.org/jira/browse/THRIFT-4328) - Travis CI builds are timing out (job 1) and haxe builds are failing since 9/11
+- [THRIFT-4329](https://issues.apache.org/jira/browse/THRIFT-4329) - c_glib Doesn't have a multiplexed processor
+- [THRIFT-4331](https://issues.apache.org/jira/browse/THRIFT-4331) - C++: TSSLSockets bug in handling huge messages, bug in handling polling
+- [THRIFT-4332](https://issues.apache.org/jira/browse/THRIFT-4332) - Binary protocol has memory leaks
+- [THRIFT-4334](https://issues.apache.org/jira/browse/THRIFT-4334) - Perl indentation incorrect when defaulting field attribute to a struct
+- [THRIFT-4339](https://issues.apache.org/jira/browse/THRIFT-4339) - Thrift Framed Transport in Erlang crashes server when client disconnects
+- [THRIFT-4340](https://issues.apache.org/jira/browse/THRIFT-4340) - Erlang fix a crash on client close
+- [THRIFT-4355](https://issues.apache.org/jira/browse/THRIFT-4355) - Javascript indentation incorrect when defaulting field attribute to a struct
+- [THRIFT-4356](https://issues.apache.org/jira/browse/THRIFT-4356) - thrift_protocol call Transport cause Segmentation fault
+- [THRIFT-4359](https://issues.apache.org/jira/browse/THRIFT-4359) - Haxe compiler looks like it is producing incorrect code for map or set key that is binary type
+- [THRIFT-4362](https://issues.apache.org/jira/browse/THRIFT-4362) - Missing size-check can lead to huge memory allocation
+- [THRIFT-4364](https://issues.apache.org/jira/browse/THRIFT-4364) - Website contributing guide erroneously recommends submitting patches in JIRA
+- [THRIFT-4365](https://issues.apache.org/jira/browse/THRIFT-4365) - Perl generated code uses indirect object syntax, which occasionally causes compilation errors.
+- [THRIFT-4367](https://issues.apache.org/jira/browse/THRIFT-4367) - python TProcessor.process is missing "self"
+- [THRIFT-4370](https://issues.apache.org/jira/browse/THRIFT-4370) - Ubuntu Artful cppcheck and flake8 are more stringent and causing SCA build job failures
+- [THRIFT-4372](https://issues.apache.org/jira/browse/THRIFT-4372) - Pipe write operations across a network are limited to 65,535 bytes per write.
+- [THRIFT-4374](https://issues.apache.org/jira/browse/THRIFT-4374) - cannot load thrift_protocol due to undefined symbol: _ZTVN10__cxxabiv120__si_class_type_infoE
+- [THRIFT-4375](https://issues.apache.org/jira/browse/THRIFT-4375) - TMemory throw bad_alloc due to counter overflow
+- [THRIFT-4376](https://issues.apache.org/jira/browse/THRIFT-4376) - Coverity high impact issue resolution
+- [THRIFT-4377](https://issues.apache.org/jira/browse/THRIFT-4377) - haxe. socket handles leak in TSimpleServer
+- [THRIFT-4381](https://issues.apache.org/jira/browse/THRIFT-4381) - Wrong isset bitfield value after transmission
+- [THRIFT-4385](https://issues.apache.org/jira/browse/THRIFT-4385) - Go remote client -u flag is broken
+- [THRIFT-4392](https://issues.apache.org/jira/browse/THRIFT-4392) - compiler/..../plugin.thrift structs mis-ordered blows up ocaml generator
+- [THRIFT-4395](https://issues.apache.org/jira/browse/THRIFT-4395) - Unable to build in the ubuntu-xenial docker image: clap 2.28 requires Rust 1.20
+- [THRIFT-4396](https://issues.apache.org/jira/browse/THRIFT-4396) - inconsistent (or plain wrong) version numbers in master/trunk
+
+### Documentation
+- [THRIFT-4157](https://issues.apache.org/jira/browse/THRIFT-4157) - outdated readme about Haxe installation on Linux
+
+### Improvement
+- [THRIFT-105](https://issues.apache.org/jira/browse/THRIFT-105) - make a thrift_spec for a structures with negative tags
+- [THRIFT-281](https://issues.apache.org/jira/browse/THRIFT-281) - Cocoa library code needs comments, badly
+- [THRIFT-775](https://issues.apache.org/jira/browse/THRIFT-775) - performance improvements for Perl
+- [THRIFT-2221](https://issues.apache.org/jira/browse/THRIFT-2221) - Generate c++ code with std::shared_ptr instead of boost::shared_ptr.
+- [THRIFT-2364](https://issues.apache.org/jira/browse/THRIFT-2364) - OCaml: Use Oasis exclusively for build process
+- [THRIFT-2504](https://issues.apache.org/jira/browse/THRIFT-2504) - TMultiplexedProcessor should allow registering default processor called if no service name is present
+- [THRIFT-3207](https://issues.apache.org/jira/browse/THRIFT-3207) - Enable build with OpenSSL 1.1.0 series
+- [THRIFT-3272](https://issues.apache.org/jira/browse/THRIFT-3272) - Perl SSL Authentication Support
+- [THRIFT-3357](https://issues.apache.org/jira/browse/THRIFT-3357) - Generate EnumSet/EnumMap where elements/keys are enums
+- [THRIFT-3369](https://issues.apache.org/jira/browse/THRIFT-3369) - Implement SSL/TLS support on C with c_glib
+- [THRIFT-3467](https://issues.apache.org/jira/browse/THRIFT-3467) - Go Maps for Thrift Sets Should Have Values of Type struct{}
+- [THRIFT-3580](https://issues.apache.org/jira/browse/THRIFT-3580) - THeader for Haskell
+- [THRIFT-3627](https://issues.apache.org/jira/browse/THRIFT-3627) - Missing basic code style consistency of JavaScript.
+- [THRIFT-3706](https://issues.apache.org/jira/browse/THRIFT-3706) - There's no support for Multiplexed protocol on c_glib library
+- [THRIFT-3766](https://issues.apache.org/jira/browse/THRIFT-3766) - Add getUnderlyingTransport() to TZlibTransport
+- [THRIFT-3776](https://issues.apache.org/jira/browse/THRIFT-3776) - Go code from multiple thrift files with the same namespace
+- [THRIFT-3823](https://issues.apache.org/jira/browse/THRIFT-3823) - Escape documentation while generating non escaped documetation
+- [THRIFT-3854](https://issues.apache.org/jira/browse/THRIFT-3854) - allow users to clear read buffers
+- [THRIFT-3859](https://issues.apache.org/jira/browse/THRIFT-3859) - Unix Domain Socket Support in Objective-C
+- [THRIFT-3921](https://issues.apache.org/jira/browse/THRIFT-3921) - C++ code should print enums as strings
+- [THRIFT-3926](https://issues.apache.org/jira/browse/THRIFT-3926) - There should be an error emitted when http status code is not 200
+- [THRIFT-4007](https://issues.apache.org/jira/browse/THRIFT-4007) - Micro-optimization of TTransport.py
+- [THRIFT-4040](https://issues.apache.org/jira/browse/THRIFT-4040) - Add real cause of TNonblockingServerSocket error to exception
+- [THRIFT-4064](https://issues.apache.org/jira/browse/THRIFT-4064) - Update node library dependencies
+- [THRIFT-4069](https://issues.apache.org/jira/browse/THRIFT-4069) - All perl packages should have proper namespace, version syntax, and use proper thrift exceptions
+- [THRIFT-4071](https://issues.apache.org/jira/browse/THRIFT-4071) - Consolidate the Travis CI jobs where possible to put less stress on the Apache Foundation's allocation of CI build slaves
+- [THRIFT-4072](https://issues.apache.org/jira/browse/THRIFT-4072) - Add the possibility to send custom headers in TCurlClient
+- [THRIFT-4075](https://issues.apache.org/jira/browse/THRIFT-4075) - Better MinGW support for headers-only boost (without thread library)
+- [THRIFT-4081](https://issues.apache.org/jira/browse/THRIFT-4081) - Provide a MinGW 64-bit Appveyor CI build for better pull request validation
+- [THRIFT-4084](https://issues.apache.org/jira/browse/THRIFT-4084) - Improve SSL security in thrift by adding a make cross client that checks to make sure SSLv3 protocol cannot be negotiated
+- [THRIFT-4095](https://issues.apache.org/jira/browse/THRIFT-4095) - Add multiplexed protocol to Travis CI for make cross
+- [THRIFT-4099](https://issues.apache.org/jira/browse/THRIFT-4099) - Auto-derive Hash for generated Rust structs
+- [THRIFT-4110](https://issues.apache.org/jira/browse/THRIFT-4110) - The debian build files do not produce a "-dbg" package for debug symbols of libthrift0
+- [THRIFT-4114](https://issues.apache.org/jira/browse/THRIFT-4114) - Space after '///' in doc comments
+- [THRIFT-4126](https://issues.apache.org/jira/browse/THRIFT-4126) - Validate objects in php extension
+- [THRIFT-4130](https://issues.apache.org/jira/browse/THRIFT-4130) - Ensure Apache Http connection is released back to pool after use
+- [THRIFT-4151](https://issues.apache.org/jira/browse/THRIFT-4151) - Thrift Mutex Contention Profiling (pthreads) should be disabled by default
+- [THRIFT-4176](https://issues.apache.org/jira/browse/THRIFT-4176) - Implement a threaded and threadpool server type for Rust
+- [THRIFT-4183](https://issues.apache.org/jira/browse/THRIFT-4183) - Named pipe client blocks forever on Open() when there is no server at the other end
+- [THRIFT-4190](https://issues.apache.org/jira/browse/THRIFT-4190) - improve C# TThreadPoolServer defaults
+- [THRIFT-4197](https://issues.apache.org/jira/browse/THRIFT-4197) - Implement transparent gzip compression for HTTP transport
+- [THRIFT-4198](https://issues.apache.org/jira/browse/THRIFT-4198) - Ruby should log Thrift internal errors to global logger
+- [THRIFT-4203](https://issues.apache.org/jira/browse/THRIFT-4203) - thrift server stop gracefully
+- [THRIFT-4205](https://issues.apache.org/jira/browse/THRIFT-4205) - c_glib is not linking against glib + gobject
+- [THRIFT-4209](https://issues.apache.org/jira/browse/THRIFT-4209) - warning CS0414 in T[TLS]ServerSocket.cs
+- [THRIFT-4210](https://issues.apache.org/jira/browse/THRIFT-4210) - include Thrift.45.csproj into CI runs
+- [THRIFT-4217](https://issues.apache.org/jira/browse/THRIFT-4217) - HttpClient should support gzip and deflate
+- [THRIFT-4222](https://issues.apache.org/jira/browse/THRIFT-4222) - Support Unix Domain Sockets in Golang TServerSocket
+- [THRIFT-4233](https://issues.apache.org/jira/browse/THRIFT-4233) - Make THsHaServer.invoker available (get method only) in inherited classes
+- [THRIFT-4236](https://issues.apache.org/jira/browse/THRIFT-4236) - Support context in go generated code.
+- [THRIFT-4238](https://issues.apache.org/jira/browse/THRIFT-4238) - JSON generator: make annotation-aware
+- [THRIFT-4269](https://issues.apache.org/jira/browse/THRIFT-4269) - Don't append '.' to Erlang namespace if it ends in '_'.
+- [THRIFT-4270](https://issues.apache.org/jira/browse/THRIFT-4270) - Generate Erlang mapping functions for const maps and lists
+- [THRIFT-4275](https://issues.apache.org/jira/browse/THRIFT-4275) - Add support for zope.interface only, apart from twisted support.
+- [THRIFT-4285](https://issues.apache.org/jira/browse/THRIFT-4285) - Pull generated send/recv into library to allow behaviour to be customised
+- [THRIFT-4287](https://issues.apache.org/jira/browse/THRIFT-4287) - Add c++ compiler "no_skeleton" flag option
+- [THRIFT-4288](https://issues.apache.org/jira/browse/THRIFT-4288) - Implement logging levels properly for node.js
+- [THRIFT-4295](https://issues.apache.org/jira/browse/THRIFT-4295) - Refresh the Docker image file suite for Ubuntu, Debian, and CentOS
+- [THRIFT-4305](https://issues.apache.org/jira/browse/THRIFT-4305) - Emit ddoc for generated items
+- [THRIFT-4306](https://issues.apache.org/jira/browse/THRIFT-4306) - Thrift imports not replicated to D service output
+- [THRIFT-4315](https://issues.apache.org/jira/browse/THRIFT-4315) - Add default message for TApplicationException
+- [THRIFT-4318](https://issues.apache.org/jira/browse/THRIFT-4318) - Delphi performance improvements
+- [THRIFT-4325](https://issues.apache.org/jira/browse/THRIFT-4325) - Simplify automake cross compilation by relying on one global THRIFT compiler path
+- [THRIFT-4327](https://issues.apache.org/jira/browse/THRIFT-4327) - Improve TimerManager API to allow removing specific task
+- [THRIFT-4330](https://issues.apache.org/jira/browse/THRIFT-4330) - Allow unused crates in Rust files
+- [THRIFT-4333](https://issues.apache.org/jira/browse/THRIFT-4333) - Erlang tutorial examples are using a different port (9999)
+- [THRIFT-4343](https://issues.apache.org/jira/browse/THRIFT-4343) - Change CI builds to use node.js 8.x LTS once available
+- [THRIFT-4345](https://issues.apache.org/jira/browse/THRIFT-4345) - Create a docker build environment that uses the minimum supported language levels
+- [THRIFT-4346](https://issues.apache.org/jira/browse/THRIFT-4346) - Allow Zlib transport factory to wrap other transports
+- [THRIFT-4348](https://issues.apache.org/jira/browse/THRIFT-4348) - Perl HTTP Client custom HTTP headers
+- [THRIFT-4350](https://issues.apache.org/jira/browse/THRIFT-4350) - Update netcore build for dotnet 2.0 sdk and make cross validation
+- [THRIFT-4351](https://issues.apache.org/jira/browse/THRIFT-4351) - Use Travis CI Build Stages to optimize the CI build
+- [THRIFT-4353](https://issues.apache.org/jira/browse/THRIFT-4353) - cannot read via thrift_protocol at server side
+- [THRIFT-4378](https://issues.apache.org/jira/browse/THRIFT-4378) - add set stopTimeoutUnit method to TThreadPoolServer
+
+### New Feature
+- [THRIFT-750](https://issues.apache.org/jira/browse/THRIFT-750) - C++ Compiler Virtual Function Option
+- [THRIFT-2945](https://issues.apache.org/jira/browse/THRIFT-2945) - Implement support for Rust language
+- [THRIFT-3857](https://issues.apache.org/jira/browse/THRIFT-3857) - thrift js:node complier support an object as parameter not an instance of struct
+- [THRIFT-3933](https://issues.apache.org/jira/browse/THRIFT-3933) - Port official C# .NET library for Thrift to C# .NET Core libary
+- [THRIFT-4039](https://issues.apache.org/jira/browse/THRIFT-4039) - Update of Apache Thrift .Net Core lib
+- [THRIFT-4113](https://issues.apache.org/jira/browse/THRIFT-4113) - Provide a buffer transport for reading/writing in memory byte stream
+
+### Question
+- [THRIFT-2956](https://issues.apache.org/jira/browse/THRIFT-2956) - autoconf - possibly undefined macro - AC_PROG_BISON
+- [THRIFT-4223](https://issues.apache.org/jira/browse/THRIFT-4223) - Add support to the isServing() method for the C++ library
+
+### Task
+- [THRIFT-3622](https://issues.apache.org/jira/browse/THRIFT-3622) - Fix deprecated uses of std::auto_ptr
+- [THRIFT-4028](https://issues.apache.org/jira/browse/THRIFT-4028) - Please remove System.out.format from the source code
+- [THRIFT-4186](https://issues.apache.org/jira/browse/THRIFT-4186) - Build and test rust client in Travis
+
+### Test
+- [THRIFT-4264](https://issues.apache.org/jira/browse/THRIFT-4264) - PHP - Support both shared & static linking of sockets library
+
+### Wish
+- [THRIFT-4344](https://issues.apache.org/jira/browse/THRIFT-4344) - Define and maintain the minimum language level for all languages in one place
+
+## 0.10.0
+
+### Bug
+- [THRIFT-1840](https://issues.apache.org/jira/browse/THRIFT-1840) - Thrift Generated Code Causes Global Variable Leaks
+- [THRIFT-1828](https://issues.apache.org/jira/browse/THRIFT-1828) - moc_TQTcpServer.cpp was removed from source tree but is in thrift-0.9.0.tar.gz
+- [THRIFT-1790](https://issues.apache.org/jira/browse/THRIFT-1790) - cocoa: Duplicate interface definition error
+- [THRIFT-1776](https://issues.apache.org/jira/browse/THRIFT-1776) - TPipeServer should implement "listen", so that TServerEventHandler preServe will work right
+- [THRIFT-1351](https://issues.apache.org/jira/browse/THRIFT-1351) - Compiler does not care about binary strings
+- [THRIFT-1229](https://issues.apache.org/jira/browse/THRIFT-1229) - Python fastbinary.c can not handle unicode as generated python code
+- [THRIFT-749](https://issues.apache.org/jira/browse/THRIFT-749) - C++ TBufferedTransports do not flush their buffers on delete
+- [THRIFT-747](https://issues.apache.org/jira/browse/THRIFT-747) - C++ TSocket->close calls shutdown breaking forked parent process
+- [THRIFT-732](https://issues.apache.org/jira/browse/THRIFT-732) - server exits abnormally when client calls send_xxx function without calling recv_xxx function
+- [THRIFT-3942](https://issues.apache.org/jira/browse/THRIFT-3942) - TSSLSocket does not honor send and receive timeouts
+- [THRIFT-3941](https://issues.apache.org/jira/browse/THRIFT-3941) - WinXP version of thrift_poll() relies on undefined behavior by passing a destructed variable to select()
+- [THRIFT-3940](https://issues.apache.org/jira/browse/THRIFT-3940) - Visual Studio project file for compiler is broken
+- [THRIFT-3943](https://issues.apache.org/jira/browse/THRIFT-3943) - Coverity Scan identified some high severity defects
+- [THRIFT-3929](https://issues.apache.org/jira/browse/THRIFT-3929) - PHP "nsglobal" Option Results in Syntax Error in Generated Code (Trailing Backslash)
+- [THRIFT-3936](https://issues.apache.org/jira/browse/THRIFT-3936) - Cannot compile 0.10.0 development tip with VS2013 and earlier (snprintf, uint32_t)
+- [THRIFT-3935](https://issues.apache.org/jira/browse/THRIFT-3935) - Incorrect skipping of map and set
+- [THRIFT-3920](https://issues.apache.org/jira/browse/THRIFT-3920) - Ruby: Ensuring that HTTP failures will clear the http transport outbuf var
+- [THRIFT-3919](https://issues.apache.org/jira/browse/THRIFT-3919) - C# TTLSServerSocket does not use clientTimeout
+- [THRIFT-3917](https://issues.apache.org/jira/browse/THRIFT-3917) - Check backports.ssl_match_hostname module version
+- [THRIFT-3909](https://issues.apache.org/jira/browse/THRIFT-3909) - Fix c_glib static lib CMake build
+- [THRIFT-3904](https://issues.apache.org/jira/browse/THRIFT-3904) - Typo in node tutorial leads to wrong transport being used
+- [THRIFT-3848](https://issues.apache.org/jira/browse/THRIFT-3848) - As an implementer of a perl socket server, I do not want to have to remember to ignore SIGCHLD for it to work properly
+- [THRIFT-3844](https://issues.apache.org/jira/browse/THRIFT-3844) - thrift_protocol cannot compile in 7.0.7
+- [THRIFT-3843](https://issues.apache.org/jira/browse/THRIFT-3843) - integer issues with Haxe PHP targets cause ZigZag encoding to fail
+- [THRIFT-3842](https://issues.apache.org/jira/browse/THRIFT-3842) - Dart generates incorrect code for a const struct
+- [THRIFT-3841](https://issues.apache.org/jira/browse/THRIFT-3841) - dart compact protocol incorrectly serializes/deserialized doubles
+- [THRIFT-3708](https://issues.apache.org/jira/browse/THRIFT-3708) - NameError: global name 'TProtocol' is not defined
+- [THRIFT-3704](https://issues.apache.org/jira/browse/THRIFT-3704) - "TConnectedClient died: Could not refill buffer" message shown when using HTTP Server
+- [THRIFT-3678](https://issues.apache.org/jira/browse/THRIFT-3678) - Fix javadoc errors on JDK 8
+- [THRIFT-3014](https://issues.apache.org/jira/browse/THRIFT-3014) - AppVeyor support
+- [THRIFT-2994](https://issues.apache.org/jira/browse/THRIFT-2994) - Node.js TJSONProtocol cannot be used for object serialization.
+- [THRIFT-2974](https://issues.apache.org/jira/browse/THRIFT-2974) - writeToParcel throws NPE for optional enum fields
+- [THRIFT-2948](https://issues.apache.org/jira/browse/THRIFT-2948) - Python TJSONProtocol doesn't handle structs with binary fields containing invalid unicode.
+- [THRIFT-2845](https://issues.apache.org/jira/browse/THRIFT-2845) - ChildService.Plo: No such file or directory
+- [THRIFT-3276](https://issues.apache.org/jira/browse/THRIFT-3276) - Binary data does not decode correctly using the TJSONProtocol when the base64 encoded data is padded.
+- [THRIFT-3253](https://issues.apache.org/jira/browse/THRIFT-3253) - Using latest version of D gives deprecation notices
+- [THRIFT-2883](https://issues.apache.org/jira/browse/THRIFT-2883) - TTwisted.py, during ConnectionLost processing: exceptions.RuntimeError: dictionary changed size during iteration
+- [THRIFT-2019](https://issues.apache.org/jira/browse/THRIFT-2019) - Writing on a disconnected socket on Mac causes SIG PIPE
+- [THRIFT-2020](https://issues.apache.org/jira/browse/THRIFT-2020) - Thrift library has some empty files that haven't really been deleted
+- [THRIFT-2049](https://issues.apache.org/jira/browse/THRIFT-2049) - Go compiler doesn't build on native Windows
+- [THRIFT-2024](https://issues.apache.org/jira/browse/THRIFT-2024) - TServer.cpp warns on 64-bit platforms about truncating an rlim_t into an int
+- [THRIFT-2023](https://issues.apache.org/jira/browse/THRIFT-2023) - gettimeofday implementation on Windows errors when no time zone is passed in.
+- [THRIFT-2022](https://issues.apache.org/jira/browse/THRIFT-2022) - CoB and dense code generation still uses TR1 bind, even though that doesn't work with clang
+- [THRIFT-2027](https://issues.apache.org/jira/browse/THRIFT-2027) - Minor 64-bit and NOMINMAX issues in C++ library
+- [THRIFT-2156](https://issues.apache.org/jira/browse/THRIFT-2156) - TServerSocket::listen() is throwing exceptions with misleading information
+- [THRIFT-2154](https://issues.apache.org/jira/browse/THRIFT-2154) - Missing <operator body
+- [THRIFT-2148](https://issues.apache.org/jira/browse/THRIFT-2148) - TNonblockingMultiFetchClient imports log4j
+- [THRIFT-2103](https://issues.apache.org/jira/browse/THRIFT-2103) - [python] Support for SSL certificates with Subject Alternative Names
+- [THRIFT-1931](https://issues.apache.org/jira/browse/THRIFT-1931) - Sending a frame size of zero to a TNonblockingServer causes an assertion failure
+- [THRIFT-1751](https://issues.apache.org/jira/browse/THRIFT-1751) - definition of increase_max_fds doesn't compile when HAVE_SYS_RESOURCE_H is not defined
+- [THRIFT-1522](https://issues.apache.org/jira/browse/THRIFT-1522) - TServerSocket potential memory leak with addrinfo *res0
+- [THRIFT-1547](https://issues.apache.org/jira/browse/THRIFT-1547) - Problems building against static libevent
+- [THRIFT-1545](https://issues.apache.org/jira/browse/THRIFT-1545) - Generated javascript code uses "for in" for looping over arrays
+- [THRIFT-1487](https://issues.apache.org/jira/browse/THRIFT-1487) - Namespace problem, compile fails on generated code
+- [THRIFT-1472](https://issues.apache.org/jira/browse/THRIFT-1472) - Configuration conflicts with boost platform include header
+- [THRIFT-6](https://issues.apache.org/jira/browse/THRIFT-6) - Thrift libraries and compiler lack version number
+- [THRIFT-1680](https://issues.apache.org/jira/browse/THRIFT-1680) - make install requires GNU make
+- [THRIFT-3869](https://issues.apache.org/jira/browse/THRIFT-3869) - Dart Tutorial build fails with Error 65 at "pub get"
+- [THRIFT-3861](https://issues.apache.org/jira/browse/THRIFT-3861) - Travis CI builds are timing out - C++TServerIntegrationTest appears to be hanging
+- [THRIFT-3855](https://issues.apache.org/jira/browse/THRIFT-3855) - In the go simple server, if Stop() is called multiple times it hangs
+- [THRIFT-3885](https://issues.apache.org/jira/browse/THRIFT-3885) - PHP: Error when readI64 in TCompactProtocol
+- [THRIFT-3883](https://issues.apache.org/jira/browse/THRIFT-3883) - Go TestAllConnection can fail with port 9090 collision
+- [THRIFT-3884](https://issues.apache.org/jira/browse/THRIFT-3884) - Fix Erlang compact protocol double endianess and boolean list
+- [THRIFT-3880](https://issues.apache.org/jira/browse/THRIFT-3880) - Erlang Compact protocol - boolean values inverted
+- [THRIFT-3879](https://issues.apache.org/jira/browse/THRIFT-3879) - Undefined evaluation order causes incorrect processing in the C++ library JSON protocol
+- [THRIFT-3851](https://issues.apache.org/jira/browse/THRIFT-3851) - Golang thrift continually adds the x/thrift content type
+- [THRIFT-3850](https://issues.apache.org/jira/browse/THRIFT-3850) - All apache builds are failing when initiated from a github pull request
+- [THRIFT-3837](https://issues.apache.org/jira/browse/THRIFT-3837) - Thift 0.9.3 can't be build with QuickCheck 2.8.2 and unordered-containers 0.2.6
+- [THRIFT-3831](https://issues.apache.org/jira/browse/THRIFT-3831) - build of test/cpp/src/TestClient.cpp fails with newer gcc on platforms with unsigned char due to narrowing conversions
+- [THRIFT-3827](https://issues.apache.org/jira/browse/THRIFT-3827) - php CompactProtocol readI64 function has bug, when value has 32bit ~64bit, Example:value=1461563457000
+- [THRIFT-3825](https://issues.apache.org/jira/browse/THRIFT-3825) - Javascript test dependency is no longer available
+- [THRIFT-3814](https://issues.apache.org/jira/browse/THRIFT-3814) - Fix contention in TNonblockingServerTest
+- [THRIFT-3793](https://issues.apache.org/jira/browse/THRIFT-3793) - Appveyor builds reference an ant version that is no longer there
+- [THRIFT-3786](https://issues.apache.org/jira/browse/THRIFT-3786) - Node.js TLS emits 'connect' before connection is ready
+- [THRIFT-3780](https://issues.apache.org/jira/browse/THRIFT-3780) - Fix dart int64 usage when compiled to js
+- [THRIFT-3789](https://issues.apache.org/jira/browse/THRIFT-3789) - Node.js lacks ability to destroy connection
+- [THRIFT-3796](https://issues.apache.org/jira/browse/THRIFT-3796) - There's no --dbg for dh_strip, maybe someone has mistaken this for --dbg-package.
+- [THRIFT-3795](https://issues.apache.org/jira/browse/THRIFT-3795) - Generated hashValue method in Swift will overflow
+- [THRIFT-3790](https://issues.apache.org/jira/browse/THRIFT-3790) - Fix Delphi named pipe client to use timeout even when pipe doesn't yet exist
+- [THRIFT-3787](https://issues.apache.org/jira/browse/THRIFT-3787) - Node.js Connection object doesn't handle errors correctly
+- [THRIFT-3791](https://issues.apache.org/jira/browse/THRIFT-3791) - Delphi pipe client may fail even in a non-error condition
+- [THRIFT-3771](https://issues.apache.org/jira/browse/THRIFT-3771) - TBufferedTransport gets in invalid state on read/write errors
+- [THRIFT-3764](https://issues.apache.org/jira/browse/THRIFT-3764) - PHP "make install" does not install TMultiplexedProtocol.php nor TSimpleJSONProtocol.php
+- [THRIFT-3768](https://issues.apache.org/jira/browse/THRIFT-3768) - TThreadedServer may crash if it is destroyed immediately after it returns from serve(); TThreadedServer disconnects clients
+- [THRIFT-3765](https://issues.apache.org/jira/browse/THRIFT-3765) - memory leak in python compact protocol extension
+- [THRIFT-3758](https://issues.apache.org/jira/browse/THRIFT-3758) - TApplicationException::getType and TProtocolException::getType should be const
+- [THRIFT-3763](https://issues.apache.org/jira/browse/THRIFT-3763) - Fix serialization of i64 larger than 2^53 for browserify
+- [THRIFT-3759](https://issues.apache.org/jira/browse/THRIFT-3759) - required fields that are nil are silently ignored on write
+- [THRIFT-3753](https://issues.apache.org/jira/browse/THRIFT-3753) - TServerFramework::stop may fail to interrupt connected clients
+- [THRIFT-3755](https://issues.apache.org/jira/browse/THRIFT-3755) - TDebugProtocol::writeString hits assert in isprint on Windows with debug CRT
+- [THRIFT-3751](https://issues.apache.org/jira/browse/THRIFT-3751) - Compiler allows field ids that are too large for generated code
+- [THRIFT-3748](https://issues.apache.org/jira/browse/THRIFT-3748) - Node.js Deserialization of lists of lists is broken
+- [THRIFT-3760](https://issues.apache.org/jira/browse/THRIFT-3760) - Fix install paths etc of debian packages for py and perl
+- [THRIFT-3757](https://issues.apache.org/jira/browse/THRIFT-3757) - Fix various build warnings on Windows with VS2015 compiler
+- [THRIFT-3750](https://issues.apache.org/jira/browse/THRIFT-3750) - NSCopying copyWithZone: implementation does not check isSet
+- [THRIFT-3747](https://issues.apache.org/jira/browse/THRIFT-3747) - Duplicate node.js build on Travis-CI
+- [THRIFT-3744](https://issues.apache.org/jira/browse/THRIFT-3744) - The precision should be 17 (16 bits need after dot) after dot for double type.
+- [THRIFT-3741](https://issues.apache.org/jira/browse/THRIFT-3741) - haxe test is broken
+- [THRIFT-3739](https://issues.apache.org/jira/browse/THRIFT-3739) - Deprecation warning in codegen/base.d
+- [THRIFT-3735](https://issues.apache.org/jira/browse/THRIFT-3735) - JSON protocol left in incorrect state when an exception is thrown during read or write operations
+- [THRIFT-3734](https://issues.apache.org/jira/browse/THRIFT-3734) - To compare two string as lowercase.
+- [THRIFT-3743](https://issues.apache.org/jira/browse/THRIFT-3743) - Java JSON protocol left in incorrect state when an exception is thrown during read or write operations
+- [THRIFT-3731](https://issues.apache.org/jira/browse/THRIFT-3731) - Perl multiplex test is flaky
+- [THRIFT-3729](https://issues.apache.org/jira/browse/THRIFT-3729) - Restrict rake version
+- [THRIFT-3727](https://issues.apache.org/jira/browse/THRIFT-3727) - Incorrect require paths in Node.js tutorial
+- [THRIFT-3723](https://issues.apache.org/jira/browse/THRIFT-3723) - Fix Lua include path
+- [THRIFT-3722](https://issues.apache.org/jira/browse/THRIFT-3722) - Fix cert path in C++ cross tests for non-Linux platform
+- [THRIFT-3726](https://issues.apache.org/jira/browse/THRIFT-3726) - Fix incorrect conditional in TMultiplexedProcessor.py
+- [THRIFT-3725](https://issues.apache.org/jira/browse/THRIFT-3725) - Skip a flaky cross test entry (d-dart compact framed-ip)
+- [THRIFT-3724](https://issues.apache.org/jira/browse/THRIFT-3724) - Fix incorrect timeval conversion in libevent.d
+- [THRIFT-3721](https://issues.apache.org/jira/browse/THRIFT-3721) - CLONE - why not add unicode strings support to python directly?
+- [THRIFT-3720](https://issues.apache.org/jira/browse/THRIFT-3720) - TTcpSocketStreamImpl.Read() returns 0 if not all requested bytes could be read
+- [THRIFT-3719](https://issues.apache.org/jira/browse/THRIFT-3719) - Dart generator should use lowerCamelCase for service names
+- [THRIFT-3902](https://issues.apache.org/jira/browse/THRIFT-3902) - TSocket.open throws NullPointerException
+- [THRIFT-3901](https://issues.apache.org/jira/browse/THRIFT-3901) - TFramedTransport.open throws NullPointerException
+- [THRIFT-3893](https://issues.apache.org/jira/browse/THRIFT-3893) - Command injection in format_go_output
+- [THRIFT-3807](https://issues.apache.org/jira/browse/THRIFT-3807) - Swift compiler does not escape reserved words
+- [THRIFT-3798](https://issues.apache.org/jira/browse/THRIFT-3798) - THttpClient does not use proxy from http_proxy, https_proxy environment variables
+- [THRIFT-3809](https://issues.apache.org/jira/browse/THRIFT-3809) - wrong/unused BINARY type code
+- [THRIFT-3806](https://issues.apache.org/jira/browse/THRIFT-3806) - Swift generator does not handle self-referring structs
+- [THRIFT-3805](https://issues.apache.org/jira/browse/THRIFT-3805) - Golang server susceptible to memory spike from malformed message
+- [THRIFT-3797](https://issues.apache.org/jira/browse/THRIFT-3797) - Generated Delphi processor shouldn't error out on timed out exceptions
+- [THRIFT-3813](https://issues.apache.org/jira/browse/THRIFT-3813) - Appveyor builds reference an openssl version that is no longer there
+- [THRIFT-3658](https://issues.apache.org/jira/browse/THRIFT-3658) - Missing file in THRIFT-3599
+- [THRIFT-3649](https://issues.apache.org/jira/browse/THRIFT-3649) - Python TSaslClientTransport initializes TTransportException incorrectly
+- [THRIFT-3650](https://issues.apache.org/jira/browse/THRIFT-3650) - incorrect union serialization
+- [THRIFT-3713](https://issues.apache.org/jira/browse/THRIFT-3713) - lib/d/test/thrift_test_runner.sh is flaky on Jenkins
+- [THRIFT-3668](https://issues.apache.org/jira/browse/THRIFT-3668) - range check error in compact protocol
+- [THRIFT-3663](https://issues.apache.org/jira/browse/THRIFT-3663) - CMake cpp test fails to build on system without zlib
+- [THRIFT-3712](https://issues.apache.org/jira/browse/THRIFT-3712) - TTornadoServer cannot handle IPv6 address
+- [THRIFT-3710](https://issues.apache.org/jira/browse/THRIFT-3710) - Dart generator does not camel case Constants class names
+- [THRIFT-3697](https://issues.apache.org/jira/browse/THRIFT-3697) - Dart generator does not name imports
+- [THRIFT-3690](https://issues.apache.org/jira/browse/THRIFT-3690) - Work around docker image build failures on Travis-CI
+- [THRIFT-3689](https://issues.apache.org/jira/browse/THRIFT-3689) - thrift_reconnecting_client start failed when server is not available
+- [THRIFT-3695](https://issues.apache.org/jira/browse/THRIFT-3695) - Fix D test scripts
+- [THRIFT-3675](https://issues.apache.org/jira/browse/THRIFT-3675) - Union is not serialized correctly by Thrift C Glib
+- [THRIFT-3673](https://issues.apache.org/jira/browse/THRIFT-3673) - API fails with std::exception after a timeout occured in earlier any API call
+- [THRIFT-3709](https://issues.apache.org/jira/browse/THRIFT-3709) - Comment syntax can produce broken code
+- [THRIFT-3705](https://issues.apache.org/jira/browse/THRIFT-3705) - Go map has incorrect types when used with forward-defined types
+- [THRIFT-3702](https://issues.apache.org/jira/browse/THRIFT-3702) - Fix cross tests for Dart compact protocol (3 failing)
+- [THRIFT-3683](https://issues.apache.org/jira/browse/THRIFT-3683) - BadYieldError in thrift py:tornado server
+- [THRIFT-3682](https://issues.apache.org/jira/browse/THRIFT-3682) - Do not reuse refused sockets in test scripts
+- [THRIFT-3681](https://issues.apache.org/jira/browse/THRIFT-3681) - Fix Dart tutorial build
+- [THRIFT-3680](https://issues.apache.org/jira/browse/THRIFT-3680) - Java async processor fails to notify errors to clients
+- [THRIFT-3714](https://issues.apache.org/jira/browse/THRIFT-3714) - Thrift.TProtocolException is not defined in js/src/thrift.js
+- [THRIFT-3688](https://issues.apache.org/jira/browse/THRIFT-3688) - Fix socket bind failure detection of cross test
+- [THRIFT-3641](https://issues.apache.org/jira/browse/THRIFT-3641) - Ruby client should try to connect to every result of getaddrinfo
+- [THRIFT-3635](https://issues.apache.org/jira/browse/THRIFT-3635) - D transport_test is flaky on Jenkins and Travis
+- [THRIFT-3618](https://issues.apache.org/jira/browse/THRIFT-3618) - Python TSSLSocket deprecation message should print caller's location
+- [THRIFT-3145](https://issues.apache.org/jira/browse/THRIFT-3145) - JSON protocol does not handle bool and empty containers correctly
+- [THRIFT-3158](https://issues.apache.org/jira/browse/THRIFT-3158) - TBase<T,F>#deepCopy should return T
+- [THRIFT-3157](https://issues.apache.org/jira/browse/THRIFT-3157) - TBase signature should be TBase<T extends TBase<T,F>, F extends TFieldIdEnum>
+- [THRIFT-3156](https://issues.apache.org/jira/browse/THRIFT-3156) - Node TLS: server executes processing logic two full times
+- [THRIFT-3154](https://issues.apache.org/jira/browse/THRIFT-3154) - tutorial/py.tornado throw EOF exception
+- [THRIFT-3063](https://issues.apache.org/jira/browse/THRIFT-3063) - C++ build -Wunused-parameter warnings on processor_test, TransportTest
+- [THRIFT-3056](https://issues.apache.org/jira/browse/THRIFT-3056) - Add string/collection length limits for Python protocol readers
+- [THRIFT-3237](https://issues.apache.org/jira/browse/THRIFT-3237) - Fix TNamedPipeServer::createNamedPipe memory leak
+- [THRIFT-3233](https://issues.apache.org/jira/browse/THRIFT-3233) - Fix C++ ThreadManager::Impl::removeWorker worker join
+- [THRIFT-3232](https://issues.apache.org/jira/browse/THRIFT-3232) - Cannot deserialize json messages created with fieldNamesAsString
+- [THRIFT-3206](https://issues.apache.org/jira/browse/THRIFT-3206) - Fix Visual Studio build failure due 'pthread_self': identifier not found
+- [THRIFT-3200](https://issues.apache.org/jira/browse/THRIFT-3200) - JS and nodejs do not encode JSON protocol binary fields as base64
+- [THRIFT-3199](https://issues.apache.org/jira/browse/THRIFT-3199) - Exception field has basic metadata
+- [THRIFT-3182](https://issues.apache.org/jira/browse/THRIFT-3182) - TFramedTransport is in an invalid state after frame size exception
+- [THRIFT-2536](https://issues.apache.org/jira/browse/THRIFT-2536) - new TSocket, uninitialised value reported by valgrind
+- [THRIFT-2527](https://issues.apache.org/jira/browse/THRIFT-2527) - Apache Thrift IDL Compiler code generated for Node.js should be jshint clean
+- [THRIFT-2519](https://issues.apache.org/jira/browse/THRIFT-2519) - "processor" class is not being generated
+- [THRIFT-2431](https://issues.apache.org/jira/browse/THRIFT-2431) - TFileTransportTest fails with "check delta < XXX failed"
+- [THRIFT-2708](https://issues.apache.org/jira/browse/THRIFT-2708) - Erlang library does not support "oneway" message type
+- [THRIFT-3377](https://issues.apache.org/jira/browse/THRIFT-3377) - Deep copy is actually shallow when using typedef members
+- [THRIFT-3376](https://issues.apache.org/jira/browse/THRIFT-3376) - C# and Python JSON protocol double values lose precision
+- [THRIFT-3373](https://issues.apache.org/jira/browse/THRIFT-3373) - Various fixes for cross test servers and clients
+- [THRIFT-3370](https://issues.apache.org/jira/browse/THRIFT-3370) - errno extern variable redefined. Not compiling for Android
+- [THRIFT-3379](https://issues.apache.org/jira/browse/THRIFT-3379) - Potential out of range panic in Go JSON protocols
+- [THRIFT-3371](https://issues.apache.org/jira/browse/THRIFT-3371) - Abstract namespace Unix domain sockets broken in C++
+- [THRIFT-3380](https://issues.apache.org/jira/browse/THRIFT-3380) - nodejs: 0.9.2 -> 0.9.3 upgrade breaks Protocol and Transport requires
+- [THRIFT-3367](https://issues.apache.org/jira/browse/THRIFT-3367) - Fix bad links to coding_standards.md #634
+- [THRIFT-3401](https://issues.apache.org/jira/browse/THRIFT-3401) - Nested collections emit Objective-C code that cannot compile
+- [THRIFT-3403](https://issues.apache.org/jira/browse/THRIFT-3403) - JSON String reader doesn't recognize UTF-16 surrogate pairs
+- [THRIFT-3362](https://issues.apache.org/jira/browse/THRIFT-3362) - make check fails for C++ at the SecurityTest
+- [THRIFT-3395](https://issues.apache.org/jira/browse/THRIFT-3395) - Cocoa compiler produces corrupt code when boxing enums inside map.
+- [THRIFT-3394](https://issues.apache.org/jira/browse/THRIFT-3394) - compiler generates uncompilable code
+- [THRIFT-3388](https://issues.apache.org/jira/browse/THRIFT-3388) - hash doesn't work on set/list
+- [THRIFT-3391](https://issues.apache.org/jira/browse/THRIFT-3391) - Wrong bool formatting in test server
+- [THRIFT-3390](https://issues.apache.org/jira/browse/THRIFT-3390) - TTornado server doesn't handle closed connections properly
+- [THRIFT-3382](https://issues.apache.org/jira/browse/THRIFT-3382) - TBase class for C++ Library
+- [THRIFT-3392](https://issues.apache.org/jira/browse/THRIFT-3392) - Java TZlibTransport does not close its wrapper streams upon close()
+- [THRIFT-3383](https://issues.apache.org/jira/browse/THRIFT-3383) - i64 related warnings
+- [THRIFT-3386](https://issues.apache.org/jira/browse/THRIFT-3386) - misc. warnings with make check
+- [THRIFT-3385](https://issues.apache.org/jira/browse/THRIFT-3385) - warning: format ‘%lu’ expects ‘long unsigned int’, but has type ‘std::basic_string<char>::size_type {aka unsigned int}
+- [THRIFT-3355](https://issues.apache.org/jira/browse/THRIFT-3355) - npm WARN package.json thrift@1.0.0-dev No license field.
+- [THRIFT-3360](https://issues.apache.org/jira/browse/THRIFT-3360) - Improve cross test servers and clients further
+- [THRIFT-3359](https://issues.apache.org/jira/browse/THRIFT-3359) - Binary field incompatibilities
+- [THRIFT-3354](https://issues.apache.org/jira/browse/THRIFT-3354) - Fix word-extraction substr bug in initialism code
+- [THRIFT-3350](https://issues.apache.org/jira/browse/THRIFT-3350) - Python JSON protocol does not encode binary as Base64
+- [THRIFT-3577](https://issues.apache.org/jira/browse/THRIFT-3577) - assertion failed at line 512 of testcontainertest.c
+- [THRIFT-3576](https://issues.apache.org/jira/browse/THRIFT-3576) - Boost test --log_format arg does not accept lowercase
+- [THRIFT-3575](https://issues.apache.org/jira/browse/THRIFT-3575) - Go compiler tries to use unexported library methods when using read_write_private
+- [THRIFT-3574](https://issues.apache.org/jira/browse/THRIFT-3574) - Cocoa generator makes uncompilable imports
+- [THRIFT-3570](https://issues.apache.org/jira/browse/THRIFT-3570) - Remove duplicate instances that are added by upstream
+- [THRIFT-3571](https://issues.apache.org/jira/browse/THRIFT-3571) - Make feature test result browsable
+- [THRIFT-3569](https://issues.apache.org/jira/browse/THRIFT-3569) - c_glib protocols do not check number of bytes read by transport
+- [THRIFT-3568](https://issues.apache.org/jira/browse/THRIFT-3568) - THeader server crashes on readSlow
+- [THRIFT-3567](https://issues.apache.org/jira/browse/THRIFT-3567) - GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
+- [THRIFT-3566](https://issues.apache.org/jira/browse/THRIFT-3566) - C++/Qt: TQTcpServerTest::test_communicate() is never executed
+- [THRIFT-3564](https://issues.apache.org/jira/browse/THRIFT-3564) - C++/Qt: potential core dump in TQTcpServer in case an exception occurs in TAsyncProcessor::process()
+- [THRIFT-3558](https://issues.apache.org/jira/browse/THRIFT-3558) - typos in c_glib tests
+- [THRIFT-3559](https://issues.apache.org/jira/browse/THRIFT-3559) - Fix awkward extra semi-colons with Cocoa container literals
+- [THRIFT-3555](https://issues.apache.org/jira/browse/THRIFT-3555) - 'configure' script does not honor --with-openssl=<path> for libcrypto for BN_init
+- [THRIFT-3554](https://issues.apache.org/jira/browse/THRIFT-3554) - Constant decls may lead to "Error: internal error: prepare_member_name_mapping() already active for different struct"
+- [THRIFT-3552](https://issues.apache.org/jira/browse/THRIFT-3552) - glib_c Memory Leak
+- [THRIFT-3551](https://issues.apache.org/jira/browse/THRIFT-3551) - Thrift perl library missing package declaration
+- [THRIFT-3549](https://issues.apache.org/jira/browse/THRIFT-3549) - Exceptions are not properly stringified in Perl library
+- [THRIFT-3546](https://issues.apache.org/jira/browse/THRIFT-3546) - NodeJS code should not be namespaced (and is currently not strict-mode compliant)
+- [THRIFT-3545](https://issues.apache.org/jira/browse/THRIFT-3545) - Container type literals do not compile
+- [THRIFT-3538](https://issues.apache.org/jira/browse/THRIFT-3538) - Remove UnboundMethodType in TProtocolDecorator
+- [THRIFT-3536](https://issues.apache.org/jira/browse/THRIFT-3536) - Error 'char' does not contain a definition for 'IsLowSurrogate' for WP7 target
+- [THRIFT-3534](https://issues.apache.org/jira/browse/THRIFT-3534) - Link error when building with Qt5
+- [THRIFT-3533](https://issues.apache.org/jira/browse/THRIFT-3533) - Can not send nil pointer as service method argument
+- [THRIFT-3507](https://issues.apache.org/jira/browse/THRIFT-3507) - THttpClient does not use proxy from http_proxy, https_proxy environment variables
+- [THRIFT-3502](https://issues.apache.org/jira/browse/THRIFT-3502) - C++ TServerSocket passes small buffer to getsockname
+- [THRIFT-3501](https://issues.apache.org/jira/browse/THRIFT-3501) - Forward slash in comment causes compiler error
+- [THRIFT-3498](https://issues.apache.org/jira/browse/THRIFT-3498) - C++ library assumes optional function pthread_attr_setschedpolicy is available
+- [THRIFT-3497](https://issues.apache.org/jira/browse/THRIFT-3497) - Build fails with "invalid use of incomplete type"
+- [THRIFT-3496](https://issues.apache.org/jira/browse/THRIFT-3496) - C++: Cob style client fails when sending a consecutive request
+- [THRIFT-3493](https://issues.apache.org/jira/browse/THRIFT-3493) - libthrift does not compile on windows using visual studio
+- [THRIFT-3488](https://issues.apache.org/jira/browse/THRIFT-3488) - warning: unused variable 'program'
+- [THRIFT-3489](https://issues.apache.org/jira/browse/THRIFT-3489) - warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
+- [THRIFT-3487](https://issues.apache.org/jira/browse/THRIFT-3487) - Full support for newer Delphi versions
+- [THRIFT-3528](https://issues.apache.org/jira/browse/THRIFT-3528) - Fix warnings in thrift.ll
+- [THRIFT-3527](https://issues.apache.org/jira/browse/THRIFT-3527) - -gen py:dynamic,utf8strings ignores utf8strings option
+- [THRIFT-3526](https://issues.apache.org/jira/browse/THRIFT-3526) - Code generated by py:utf8strings does not work for Python3
+- [THRIFT-3524](https://issues.apache.org/jira/browse/THRIFT-3524) - dcc32 warning "W1000 Symbol 'IsLowSurrogate' is deprecated: 'Use TCharHelper'" in Thrift.Protocol.JSON.pas
+- [THRIFT-3525](https://issues.apache.org/jira/browse/THRIFT-3525) - py:dynamic fails to handle binary list/set/map element
+- [THRIFT-3521](https://issues.apache.org/jira/browse/THRIFT-3521) - TSimpleJSONProtocolTest is not deterministic (fails when run on JDK 8)
+- [THRIFT-3520](https://issues.apache.org/jira/browse/THRIFT-3520) - Dart TSocket onError stream should be typed as Object
+- [THRIFT-3519](https://issues.apache.org/jira/browse/THRIFT-3519) - fastbinary does not work with -gen py:utf8strings
+- [THRIFT-3518](https://issues.apache.org/jira/browse/THRIFT-3518) - TConcurrentClientSyncInfo files were missing for Visual Studio
+- [THRIFT-3512](https://issues.apache.org/jira/browse/THRIFT-3512) - c_glib: Build fails due to missing features.h
+- [THRIFT-3483](https://issues.apache.org/jira/browse/THRIFT-3483) - Incorrect empty binary handling introduced by THRIFT-3359
+- [THRIFT-3479](https://issues.apache.org/jira/browse/THRIFT-3479) - Oneway calls should not return exceptions to clients
+- [THRIFT-3478](https://issues.apache.org/jira/browse/THRIFT-3478) - Restore dropped method to THsHaServer.java
+- [THRIFT-3477](https://issues.apache.org/jira/browse/THRIFT-3477) - Parser fails on enum item that starts with 'E' letter and continues with number
+- [THRIFT-3476](https://issues.apache.org/jira/browse/THRIFT-3476) - Missing include in ./src/thrift/protocol/TJSONProtocol.cpp
+- [THRIFT-3474](https://issues.apache.org/jira/browse/THRIFT-3474) - Docker: thrift-compiler
+- [THRIFT-3473](https://issues.apache.org/jira/browse/THRIFT-3473) - When "optional' is used with a struct member, C++ server seems to not return it correctly
+- [THRIFT-3468](https://issues.apache.org/jira/browse/THRIFT-3468) - Dart TSocketTransport onError handler is too restrictive
+- [THRIFT-3451](https://issues.apache.org/jira/browse/THRIFT-3451) - thrift_protocol PHP extension missing config.m4 file
+- [THRIFT-3456](https://issues.apache.org/jira/browse/THRIFT-3456) - rounding issue in static assert
+- [THRIFT-3455](https://issues.apache.org/jira/browse/THRIFT-3455) - struct write method's return value is incorrect
+- [THRIFT-3454](https://issues.apache.org/jira/browse/THRIFT-3454) - Python Tornado tutorial is broken
+- [THRIFT-3463](https://issues.apache.org/jira/browse/THRIFT-3463) - Java can't be disabled in CMake build
+- [THRIFT-3450](https://issues.apache.org/jira/browse/THRIFT-3450) - NPE when using SSL
+- [THRIFT-3449](https://issues.apache.org/jira/browse/THRIFT-3449) - TBaseAsyncProcessor fb.responseReady() never called for oneway functions
+- [THRIFT-3471](https://issues.apache.org/jira/browse/THRIFT-3471) - Dart generator does not handle uppercase argument names
+- [THRIFT-3470](https://issues.apache.org/jira/browse/THRIFT-3470) - Sporadic timeouts with pipes
+- [THRIFT-3465](https://issues.apache.org/jira/browse/THRIFT-3465) - Go Code With Complex Const Initializer Compilation Depends On Struct Order
+- [THRIFT-3464](https://issues.apache.org/jira/browse/THRIFT-3464) - Fix several defects in c_glib code generator
+- [THRIFT-3462](https://issues.apache.org/jira/browse/THRIFT-3462) - Cocoa generates Incorrect #import header names
+- [THRIFT-3453](https://issues.apache.org/jira/browse/THRIFT-3453) - remove rat_exclude
+- [THRIFT-3418](https://issues.apache.org/jira/browse/THRIFT-3418) - Use of ciphers in ssl.wrap_socket() breaks python 2.6 compatibility
+- [THRIFT-3417](https://issues.apache.org/jira/browse/THRIFT-3417) - "namespace xsd" is not really working
+- [THRIFT-3413](https://issues.apache.org/jira/browse/THRIFT-3413) - Thrift code generation bug in Go when extending service
+- [THRIFT-3420](https://issues.apache.org/jira/browse/THRIFT-3420) - C++: TSSLSockets are not interruptable
+- [THRIFT-3415](https://issues.apache.org/jira/browse/THRIFT-3415) - include unistd.h conditionally
+- [THRIFT-3414](https://issues.apache.org/jira/browse/THRIFT-3414) - #include <pwd.h> in THeaderTransport.h breaks windows build
+- [THRIFT-3411](https://issues.apache.org/jira/browse/THRIFT-3411) - Go generates remotes with wrong package qualifiers when including
+- [THRIFT-3430](https://issues.apache.org/jira/browse/THRIFT-3430) - Go THttpClient does not read HTTP response body to completion when closing
+- [THRIFT-3423](https://issues.apache.org/jira/browse/THRIFT-3423) - First call to thrift_transport:read_exact fails to dispatch correct function
+- [THRIFT-3422](https://issues.apache.org/jira/browse/THRIFT-3422) - Go TServerSocket doesn't close on Interrupt
+- [THRIFT-3421](https://issues.apache.org/jira/browse/THRIFT-3421) - rebar as dependency instead of bundling (was: rebar fails if PWD contains Unicode)
+- [THRIFT-3428](https://issues.apache.org/jira/browse/THRIFT-3428) - Go test fails when running make check
+- [THRIFT-3445](https://issues.apache.org/jira/browse/THRIFT-3445) - Throwable messages are hidden from JVM stack trace output
+- [THRIFT-3443](https://issues.apache.org/jira/browse/THRIFT-3443) - Thrift include can generate uncompilable code
+- [THRIFT-3444](https://issues.apache.org/jira/browse/THRIFT-3444) - Large 64 bit Integer does not preserve value through Node.js JSONProtocol
+- [THRIFT-3436](https://issues.apache.org/jira/browse/THRIFT-3436) - misc. cross test issues with UTF-8 path names
+- [THRIFT-3435](https://issues.apache.org/jira/browse/THRIFT-3435) - Put generated Java code for fullcamel tests in a separate package/namespace
+- [THRIFT-3433](https://issues.apache.org/jira/browse/THRIFT-3433) - Doubles aren't interpreted correctly
+- [THRIFT-3437](https://issues.apache.org/jira/browse/THRIFT-3437) - Mingw-w64 build fail
+- [THRIFT-3434](https://issues.apache.org/jira/browse/THRIFT-3434) - Dart generator produces empty name in pubspec.yaml for includes without namespaces
+- [THRIFT-3408](https://issues.apache.org/jira/browse/THRIFT-3408) - JSON generator emits incorrect types
+- [THRIFT-3406](https://issues.apache.org/jira/browse/THRIFT-3406) - Cocoa client should not schedule streams on main runloop
+- [THRIFT-3404](https://issues.apache.org/jira/browse/THRIFT-3404) - JSON String reader doesn't recognize UTF-16 surrogate pair
+- [THRIFT-3636](https://issues.apache.org/jira/browse/THRIFT-3636) - Double precision is not fully preserved in C++ TJSONProtocol
+- [THRIFT-3632](https://issues.apache.org/jira/browse/THRIFT-3632) - c_glib testserialization fails with glib assertion
+- [THRIFT-3619](https://issues.apache.org/jira/browse/THRIFT-3619) - Using Thrift 0.9.3 with googletest on Linux gcc 4.9 / C++11
+- [THRIFT-3617](https://issues.apache.org/jira/browse/THRIFT-3617) - CMake does not build gv/xml generators
+- [THRIFT-3615](https://issues.apache.org/jira/browse/THRIFT-3615) - Fix Python SSL client resource leak on connection failure
+- [THRIFT-3616](https://issues.apache.org/jira/browse/THRIFT-3616) - lib/py/test/test_sslsocket.py is flaky
+- [THRIFT-3643](https://issues.apache.org/jira/browse/THRIFT-3643) - Perl SSL server crushes if a client disconnect without handshake
+- [THRIFT-3639](https://issues.apache.org/jira/browse/THRIFT-3639) - C# Thrift library forces TLS 1.0, thwarting TLS 1.2 usage
+- [THRIFT-3633](https://issues.apache.org/jira/browse/THRIFT-3633) - Travis "C C++ - GCC" build was using clang
+- [THRIFT-3634](https://issues.apache.org/jira/browse/THRIFT-3634) - Fix Python TSocket resource leak on connection failure
+- [THRIFT-3630](https://issues.apache.org/jira/browse/THRIFT-3630) - Debian/Ubuntu install docs need an update
+- [THRIFT-3629](https://issues.apache.org/jira/browse/THRIFT-3629) - Parser sets exitcode on errors, but generator does not
+- [THRIFT-3608](https://issues.apache.org/jira/browse/THRIFT-3608) - lib/cpp/test/SecurityTest is flaky in jenkins Thrift-precommit build.
+- [THRIFT-3601](https://issues.apache.org/jira/browse/THRIFT-3601) - Better conformance to PEP8 for generated code
+- [THRIFT-3599](https://issues.apache.org/jira/browse/THRIFT-3599) - Validate client IP address against cert's SubjectAltName
+- [THRIFT-3598](https://issues.apache.org/jira/browse/THRIFT-3598) - TBufferedTransport doesn't instantiate client connection
+- [THRIFT-3597](https://issues.apache.org/jira/browse/THRIFT-3597) - `make check` hangs in go tests
+- [THRIFT-3589](https://issues.apache.org/jira/browse/THRIFT-3589) - Dart generator uses wrong name in constructor for uppercase arguments with defaults
+- [THRIFT-3588](https://issues.apache.org/jira/browse/THRIFT-3588) - Using TypeScript with --noImplicitAny fails
+- [THRIFT-3584](https://issues.apache.org/jira/browse/THRIFT-3584) - boolean false value cannot be transferred
+- [THRIFT-3578](https://issues.apache.org/jira/browse/THRIFT-3578) - Make THeaderTransport detect TCompact framed and unframed
+- [THRIFT-3323](https://issues.apache.org/jira/browse/THRIFT-3323) - Python library does not handle escaped forward slash ("/") in JSON
+- [THRIFT-3322](https://issues.apache.org/jira/browse/THRIFT-3322) - CMake generated "make check" failes on python_test
+- [THRIFT-3321](https://issues.apache.org/jira/browse/THRIFT-3321) - Thrift can't be added as a subdirectory of another CMake-based project
+- [THRIFT-3314](https://issues.apache.org/jira/browse/THRIFT-3314) - Dots in file names of includes causes dots in javascript variable names
+- [THRIFT-3307](https://issues.apache.org/jira/browse/THRIFT-3307) - Segfault in Ruby serializer
+- [THRIFT-3309](https://issues.apache.org/jira/browse/THRIFT-3309) - Missing TConstant.php in /lib/php/Makefile.am
+- [THRIFT-3810](https://issues.apache.org/jira/browse/THRIFT-3810) - unresolved external symbol public: virtual void __cdecl apache::thrift::server::TServerFramework::serve(void)
+- [THRIFT-3736](https://issues.apache.org/jira/browse/THRIFT-3736) - C++ library build fails if OpenSSL does not surrpot SSLv3
+- [THRIFT-3878](https://issues.apache.org/jira/browse/THRIFT-3878) - Compile error in TSSLSocket.cpp with new OpenSSL [CRYPTO_num_locks]
+- [THRIFT-3949](https://issues.apache.org/jira/browse/THRIFT-3949) - missing make dist entry for compiler/cpp/test
+- [THRIFT-449](https://issues.apache.org/jira/browse/THRIFT-449) - The wire format of the JSON Protocol may not always be valid JSON if it contains non-UTF8 encoded strings
+- [THRIFT-162](https://issues.apache.org/jira/browse/THRIFT-162) - Thrift structures are unhashable, preventing them from being used as set elements
+- [THRIFT-3961](https://issues.apache.org/jira/browse/THRIFT-3961) - TConnectedClient does not terminate the connection to the client if an exception while processing the received message occures.
+- [THRIFT-3881](https://issues.apache.org/jira/browse/THRIFT-3881) - Travis CI builds are failing due to docker failures (three retries, and gives up)
+- [THRIFT-3937](https://issues.apache.org/jira/browse/THRIFT-3937) - Cannot compile 0.10.0 development tip with gcc-4.6.x
+- [THRIFT-3964](https://issues.apache.org/jira/browse/THRIFT-3964) - Unsupported mechanism type ????? due to dependency on default OS-dependent charset
+- [THRIFT-3038](https://issues.apache.org/jira/browse/THRIFT-3038) - Use of volatile in cpp library
+- [THRIFT-3301](https://issues.apache.org/jira/browse/THRIFT-3301) - Java generated code uses imports that can lead to class name collisions with IDL defined types
+- [THRIFT-3348](https://issues.apache.org/jira/browse/THRIFT-3348) - PHP TCompactProtocol bool&int64 readvalue bug
+- [THRIFT-3955](https://issues.apache.org/jira/browse/THRIFT-3955) - TThreadedServer Memory Leak
+- [THRIFT-3829](https://issues.apache.org/jira/browse/THRIFT-3829) - Thrift does not install Python Libraries if Twisted is not installed
+- [THRIFT-3932](https://issues.apache.org/jira/browse/THRIFT-3932) - C++ ThreadManager has a rare termination race
+- [THRIFT-3828](https://issues.apache.org/jira/browse/THRIFT-3828) - cmake fails when Boost_INCLUDE_DIRS (and other variables passed to include_directories()) is empty
+- [THRIFT-3958](https://issues.apache.org/jira/browse/THRIFT-3958) - CMake WITH_MT option for windows static runtime linking does not support the cmake build type RelWithDebInfo
+- [THRIFT-3957](https://issues.apache.org/jira/browse/THRIFT-3957) - TConnectedClient does not disconnect from clients when their timeout is reached.
+- [THRIFT-3953](https://issues.apache.org/jira/browse/THRIFT-3953) - TSSLSocket::close should handle exceptions from waitForEvent because it is called by the destructor.
+- [THRIFT-3977](https://issues.apache.org/jira/browse/THRIFT-3977) - PHP extension creates undefined values when deserializing sets
+- [THRIFT-3947](https://issues.apache.org/jira/browse/THRIFT-3947) - sockaddr type isn't always large enough for the return of getsockname
+- [THRIFT-2755](https://issues.apache.org/jira/browse/THRIFT-2755) - ThreadSanitizer reports data race in ThreadManager::Impl::addWorker
+- [THRIFT-3948](https://issues.apache.org/jira/browse/THRIFT-3948) - errno is not the correct method of getting the error in windows
+- [THRIFT-4008](https://issues.apache.org/jira/browse/THRIFT-4008) - broken ci due to upstream dependency versioning break
+- [THRIFT-3999](https://issues.apache.org/jira/browse/THRIFT-3999) - Fix Debian & Ubuntu package dependencies
+- [THRIFT-3886](https://issues.apache.org/jira/browse/THRIFT-3886) - PHP cross test client returns 0 even when failing
+- [THRIFT-3997](https://issues.apache.org/jira/browse/THRIFT-3997) - building thrift libs does not support new openssl
+
+### Documentation
+- [THRIFT-3867](https://issues.apache.org/jira/browse/THRIFT-3867) - Specify BinaryProtocol and CompactProtocol
+
+### Epic
+- [THRIFT-3049](https://issues.apache.org/jira/browse/THRIFT-3049) - As an iOS developer, I want a generator and library that produces Swift code
+- [THRIFT-2336](https://issues.apache.org/jira/browse/THRIFT-2336) - UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
+
+### Improvement
+- [THRIFT-1867](https://issues.apache.org/jira/browse/THRIFT-1867) - Python client/server should support client-side certificates.
+- [THRIFT-1313](https://issues.apache.org/jira/browse/THRIFT-1313) - c_glib compact support
+- [THRIFT-1385](https://issues.apache.org/jira/browse/THRIFT-1385) - make install doesn't install java library in the setted folder
+- [THRIFT-1437](https://issues.apache.org/jira/browse/THRIFT-1437) - Update RPM spec
+- [THRIFT-847](https://issues.apache.org/jira/browse/THRIFT-847) - Test Framework harmonization across all languages
+- [THRIFT-819](https://issues.apache.org/jira/browse/THRIFT-819) - add Enumeration for protocol, transport and server types
+- [THRIFT-3927](https://issues.apache.org/jira/browse/THRIFT-3927) - Emit an error instead of throw an error in the async callback
+- [THRIFT-3931](https://issues.apache.org/jira/browse/THRIFT-3931) - TSimpleServer: If process request encounter UNKNOWN_METHOD, don't close transport.
+- [THRIFT-3934](https://issues.apache.org/jira/browse/THRIFT-3934) - Automatically resolve OpenSSL binary version on Windows CI
+- [THRIFT-3918](https://issues.apache.org/jira/browse/THRIFT-3918) - Run subset of make cross
+- [THRIFT-3908](https://issues.apache.org/jira/browse/THRIFT-3908) - Remove redundant dependencies from Dockerfile
+- [THRIFT-3907](https://issues.apache.org/jira/browse/THRIFT-3907) - Skip Docker image build on CI when unchanged
+- [THRIFT-3868](https://issues.apache.org/jira/browse/THRIFT-3868) - Java struct equals should do identity check before field comparison
+- [THRIFT-3849](https://issues.apache.org/jira/browse/THRIFT-3849) - Port Go serializer and deserializer to dart
+- [THRIFT-2989](https://issues.apache.org/jira/browse/THRIFT-2989) - Complete CMake build for Apache Thrift
+- [THRIFT-2980](https://issues.apache.org/jira/browse/THRIFT-2980) - ThriftMemoryBuffer doesn't have a constructor option to take an existing buffer
+- [THRIFT-2856](https://issues.apache.org/jira/browse/THRIFT-2856) - refactor erlang basic transports and unify interfaces
+- [THRIFT-2877](https://issues.apache.org/jira/browse/THRIFT-2877) - Optimize generated hashCode
+- [THRIFT-2869](https://issues.apache.org/jira/browse/THRIFT-2869) - JSON: run schema validation from tests
+- [THRIFT-3112](https://issues.apache.org/jira/browse/THRIFT-3112) - [Java] AsyncMethodCallback should be typed in generated AsyncIface
+- [THRIFT-3263](https://issues.apache.org/jira/browse/THRIFT-3263) - PHP jsonSerialize() should cast scalar types
+- [THRIFT-2905](https://issues.apache.org/jira/browse/THRIFT-2905) - Cocoa compiler should have option to produce "modern" Objective-C
+- [THRIFT-2821](https://issues.apache.org/jira/browse/THRIFT-2821) - Enable the use of custom HTTP-Header in the Transport
+- [THRIFT-2093](https://issues.apache.org/jira/browse/THRIFT-2093) - added the ability to set compression level in C++ zlib transport
+- [THRIFT-2089](https://issues.apache.org/jira/browse/THRIFT-2089) - Compiler ignores duplicate typenames
+- [THRIFT-2056](https://issues.apache.org/jira/browse/THRIFT-2056) - Moved all #include config.h statements to #include <thrift/config.h>
+- [THRIFT-2031](https://issues.apache.org/jira/browse/THRIFT-2031) - Make SO_KEEPALIVE configurable for C++ lib
+- [THRIFT-2021](https://issues.apache.org/jira/browse/THRIFT-2021) - Improve large binary protocol string performance
+- [THRIFT-2028](https://issues.apache.org/jira/browse/THRIFT-2028) - Cleanup threading headers / libraries
+- [THRIFT-2014](https://issues.apache.org/jira/browse/THRIFT-2014) - Change C++ lib includes to use <namespace/> style throughout
+- [THRIFT-2312](https://issues.apache.org/jira/browse/THRIFT-2312) - travis.yml: build everything
+- [THRIFT-1915](https://issues.apache.org/jira/browse/THRIFT-1915) - Multiplexing Services
+- [THRIFT-1736](https://issues.apache.org/jira/browse/THRIFT-1736) - Visual Studio top level project files within msvc
+- [THRIFT-1735](https://issues.apache.org/jira/browse/THRIFT-1735) - integrate tutorial into regular build
+- [THRIFT-1533](https://issues.apache.org/jira/browse/THRIFT-1533) - Make TTransport should be Closeable
+- [THRIFT-35](https://issues.apache.org/jira/browse/THRIFT-35) - Move language tests into their appropriate library directory
+- [THRIFT-1079](https://issues.apache.org/jira/browse/THRIFT-1079) - Support i64 in AS3
+- [THRIFT-1108](https://issues.apache.org/jira/browse/THRIFT-1108) - SSL support for the Ruby library
+- [THRIFT-3856](https://issues.apache.org/jira/browse/THRIFT-3856) - update debian package deependencies
+- [THRIFT-3833](https://issues.apache.org/jira/browse/THRIFT-3833) - haxe http server implementation (by embeding into php web server)
+- [THRIFT-3839](https://issues.apache.org/jira/browse/THRIFT-3839) - Performance issue with big message deserialization using php extension
+- [THRIFT-3820](https://issues.apache.org/jira/browse/THRIFT-3820) - Erlang: Detect OTP >= 18 to use new time correction
+- [THRIFT-3816](https://issues.apache.org/jira/browse/THRIFT-3816) - Reduce docker build duration on Travis-CI
+- [THRIFT-3815](https://issues.apache.org/jira/browse/THRIFT-3815) - Put appveyor dependency versions to one place
+- [THRIFT-3788](https://issues.apache.org/jira/browse/THRIFT-3788) - Compatibility improvements and Win64 support
+- [THRIFT-3792](https://issues.apache.org/jira/browse/THRIFT-3792) - Timeouts for anonymous pipes should be configurable
+- [THRIFT-3794](https://issues.apache.org/jira/browse/THRIFT-3794) - Split Delphi application, protocol and transport exception subtypes into separate exceptions
+- [THRIFT-3774](https://issues.apache.org/jira/browse/THRIFT-3774) - The generated code should have exception_names meta info
+- [THRIFT-3762](https://issues.apache.org/jira/browse/THRIFT-3762) - Fix build warnings for deprecated Thrift "byte" fields
+- [THRIFT-3756](https://issues.apache.org/jira/browse/THRIFT-3756) - Improve requiredness documentation
+- [THRIFT-3761](https://issues.apache.org/jira/browse/THRIFT-3761) - Add debian package for Python3
+- [THRIFT-3742](https://issues.apache.org/jira/browse/THRIFT-3742) - haxe php cli support
+- [THRIFT-3733](https://issues.apache.org/jira/browse/THRIFT-3733) - Socket timeout improvements
+- [THRIFT-3728](https://issues.apache.org/jira/browse/THRIFT-3728) - http transport for thrift-lua
+- [THRIFT-3905](https://issues.apache.org/jira/browse/THRIFT-3905) - Dart compiler does not initialize bool, int, and double properties
+- [THRIFT-3911](https://issues.apache.org/jira/browse/THRIFT-3911) - Loosen Ruby dev dependency version requirements
+- [THRIFT-3906](https://issues.apache.org/jira/browse/THRIFT-3906) - Run C# tests with make check
+- [THRIFT-3900](https://issues.apache.org/jira/browse/THRIFT-3900) - Add Python SSL flags
+- [THRIFT-3897](https://issues.apache.org/jira/browse/THRIFT-3897) - Provide meaningful exception type based on WebExceptionStatus in case of timeout
+- [THRIFT-3808](https://issues.apache.org/jira/browse/THRIFT-3808) - Missing `DOUBLE` in thrift type enumeration
+- [THRIFT-3803](https://issues.apache.org/jira/browse/THRIFT-3803) - Remove "file" attribute from XML generator
+- [THRIFT-3660](https://issues.apache.org/jira/browse/THRIFT-3660) - Add V4 mapped address to test client cert's altname
+- [THRIFT-3661](https://issues.apache.org/jira/browse/THRIFT-3661) - Use https to download meck in erlang test build
+- [THRIFT-3659](https://issues.apache.org/jira/browse/THRIFT-3659) - Check configure result of CMake on CI
+- [THRIFT-3667](https://issues.apache.org/jira/browse/THRIFT-3667) - Add TLS SNI support to clients
+- [THRIFT-3651](https://issues.apache.org/jira/browse/THRIFT-3651) - Make backports.match_hostname and ipaddress optional
+- [THRIFT-3666](https://issues.apache.org/jira/browse/THRIFT-3666) - Build D tutorial as part of Autotools build
+- [THRIFT-3665](https://issues.apache.org/jira/browse/THRIFT-3665) - Add D libevent and OpenSSL to docker images
+- [THRIFT-3664](https://issues.apache.org/jira/browse/THRIFT-3664) - Remove md5.c
+- [THRIFT-3662](https://issues.apache.org/jira/browse/THRIFT-3662) - Add Haskell to debian docker image
+- [THRIFT-3711](https://issues.apache.org/jira/browse/THRIFT-3711) - Add D to cross language test
+- [THRIFT-3691](https://issues.apache.org/jira/browse/THRIFT-3691) - Run flake8 Python style check on Travis-CI
+- [THRIFT-3692](https://issues.apache.org/jira/browse/THRIFT-3692) - (Re)enable Appveyor C++ and Python build
+- [THRIFT-3677](https://issues.apache.org/jira/browse/THRIFT-3677) - Improve CMake Java build
+- [THRIFT-3679](https://issues.apache.org/jira/browse/THRIFT-3679) - Add stdout log to testBinary in Java test server
+- [THRIFT-3718](https://issues.apache.org/jira/browse/THRIFT-3718) - Reduce size of docker image for build environment
+- [THRIFT-3698](https://issues.apache.org/jira/browse/THRIFT-3698) - [Travis-CI] Introduce retry to apt commands
+- [THRIFT-3127](https://issues.apache.org/jira/browse/THRIFT-3127) - switch -recurse to --recurse and reserve -r
+- [THRIFT-3087](https://issues.apache.org/jira/browse/THRIFT-3087) - Pass on errors like "connection closed"
+- [THRIFT-3240](https://issues.apache.org/jira/browse/THRIFT-3240) - Thrift Python client should support subjectAltName and wildcard certs in TSSLSocket
+- [THRIFT-3213](https://issues.apache.org/jira/browse/THRIFT-3213) - make cross should indicate when it skips a known failing test
+- [THRIFT-3208](https://issues.apache.org/jira/browse/THRIFT-3208) - Fix Visual Studio solution build failure due to missing source
+- [THRIFT-3186](https://issues.apache.org/jira/browse/THRIFT-3186) - Add TServerHTTP to Go library
+- [THRIFT-2342](https://issues.apache.org/jira/browse/THRIFT-2342) - Add __FILE__ and __LINE__ to Thrift C++ excpetions
+- [THRIFT-3372](https://issues.apache.org/jira/browse/THRIFT-3372) - Add dart generator to Visual Studio project
+- [THRIFT-3366](https://issues.apache.org/jira/browse/THRIFT-3366) - ThriftTest to implement standard return values
+- [THRIFT-3402](https://issues.apache.org/jira/browse/THRIFT-3402) - Provide a perl Unix Socket implementation
+- [THRIFT-3361](https://issues.apache.org/jira/browse/THRIFT-3361) - Improve C# library
+- [THRIFT-3393](https://issues.apache.org/jira/browse/THRIFT-3393) - Introduce i8 to provide consistent set of Thrift IDL integer types
+- [THRIFT-3339](https://issues.apache.org/jira/browse/THRIFT-3339) - Support for database/sql
+- [THRIFT-3565](https://issues.apache.org/jira/browse/THRIFT-3565) - C++: T[Async]Processor::getEventHandler() should be declared as const member functions
+- [THRIFT-3563](https://issues.apache.org/jira/browse/THRIFT-3563) - C++/Qt: removed usage of macro QT_PREPEND_NAMESPACE as it isn't consequently used for all references to Qt types.
+- [THRIFT-3562](https://issues.apache.org/jira/browse/THRIFT-3562) - Removed unused TAsyncProcessor::getAsyncServer()
+- [THRIFT-3561](https://issues.apache.org/jira/browse/THRIFT-3561) - C++/Qt: make use of Q_DISABLE_COPY() to get rid of copy ctor and assignment operator
+- [THRIFT-3556](https://issues.apache.org/jira/browse/THRIFT-3556) - c_glib file descriptor transport
+- [THRIFT-3544](https://issues.apache.org/jira/browse/THRIFT-3544) - Make cross test fail when server process died unexpectedly
+- [THRIFT-3540](https://issues.apache.org/jira/browse/THRIFT-3540) - Make python tutorial more in line with PEP8
+- [THRIFT-3535](https://issues.apache.org/jira/browse/THRIFT-3535) - Dart generator argument to produce a file structure usable in parent library
+- [THRIFT-3505](https://issues.apache.org/jira/browse/THRIFT-3505) - Enhance Python TSSLSocket
+- [THRIFT-3506](https://issues.apache.org/jira/browse/THRIFT-3506) - Eliminate old style classes from library code
+- [THRIFT-3503](https://issues.apache.org/jira/browse/THRIFT-3503) - Enable py:utf8string by default
+- [THRIFT-3499](https://issues.apache.org/jira/browse/THRIFT-3499) - Add package_prefix to python generator
+- [THRIFT-3495](https://issues.apache.org/jira/browse/THRIFT-3495) - Minor enhancements and fixes for cross test
+- [THRIFT-3486](https://issues.apache.org/jira/browse/THRIFT-3486) - Java generated `getFieldValue` is incompatible with `setFieldValue` for binary values.
+- [THRIFT-3484](https://issues.apache.org/jira/browse/THRIFT-3484) - Consolidate temporary buffers in Java's TCompactProtocol
+- [THRIFT-3516](https://issues.apache.org/jira/browse/THRIFT-3516) - Add feature test for THeader TBinaryProtocol interop
+- [THRIFT-3515](https://issues.apache.org/jira/browse/THRIFT-3515) - Python 2.6 compatibility and test on CI
+- [THRIFT-3514](https://issues.apache.org/jira/browse/THRIFT-3514) - PHP 7 compatible version of binary protocol
+- [THRIFT-3469](https://issues.apache.org/jira/browse/THRIFT-3469) - Docker: Debian support
+- [THRIFT-3416](https://issues.apache.org/jira/browse/THRIFT-3416) - Retire old "xxx_namespace" declarations from the IDL
+- [THRIFT-3426](https://issues.apache.org/jira/browse/THRIFT-3426) - Align autogen comment in XSD
+- [THRIFT-3424](https://issues.apache.org/jira/browse/THRIFT-3424) - Add CMake android build option
+- [THRIFT-3439](https://issues.apache.org/jira/browse/THRIFT-3439) - Run make cross using Python3 when available
+- [THRIFT-3440](https://issues.apache.org/jira/browse/THRIFT-3440) - Python make check takes too much time
+- [THRIFT-3441](https://issues.apache.org/jira/browse/THRIFT-3441) - Stabilize Travis-CI builds
+- [THRIFT-3431](https://issues.apache.org/jira/browse/THRIFT-3431) - Avoid "schemes" HashMap lookups during struct reads/writes
+- [THRIFT-3432](https://issues.apache.org/jira/browse/THRIFT-3432) - Add a TByteBuffer transport to the Java library
+- [THRIFT-3438](https://issues.apache.org/jira/browse/THRIFT-3438) - Enable py:new_style by default
+- [THRIFT-3405](https://issues.apache.org/jira/browse/THRIFT-3405) - Go THttpClient misuses http.Client objects
+- [THRIFT-3614](https://issues.apache.org/jira/browse/THRIFT-3614) - Improve logging of test_sslsocket.py
+- [THRIFT-3647](https://issues.apache.org/jira/browse/THRIFT-3647) - Fix php extension build warnings
+- [THRIFT-3642](https://issues.apache.org/jira/browse/THRIFT-3642) - Speed up cross test runner
+- [THRIFT-3637](https://issues.apache.org/jira/browse/THRIFT-3637) - Implement compact protocol for dart
+- [THRIFT-3613](https://issues.apache.org/jira/browse/THRIFT-3613) - Port Python C extension to Python 3
+- [THRIFT-3612](https://issues.apache.org/jira/browse/THRIFT-3612) - Add Python C extension for compact protocol
+- [THRIFT-3611](https://issues.apache.org/jira/browse/THRIFT-3611) - Add --regex filter to cross test runner
+- [THRIFT-3631](https://issues.apache.org/jira/browse/THRIFT-3631) - JSON protocol implementation for Lua
+- [THRIFT-3609](https://issues.apache.org/jira/browse/THRIFT-3609) - Remove or replace TestPortFixture.h
+- [THRIFT-3605](https://issues.apache.org/jira/browse/THRIFT-3605) - Have the compiler complain about invalid arguments and options
+- [THRIFT-3596](https://issues.apache.org/jira/browse/THRIFT-3596) - Better conformance to PEP8
+- [THRIFT-3585](https://issues.apache.org/jira/browse/THRIFT-3585) - Compact protocol implementation for Lua
+- [THRIFT-3582](https://issues.apache.org/jira/browse/THRIFT-3582) - Erlang libraries should have service metadata
+- [THRIFT-3579](https://issues.apache.org/jira/browse/THRIFT-3579) - Introduce retry to make cross
+- [THRIFT-3306](https://issues.apache.org/jira/browse/THRIFT-3306) - Java: TBinaryProtocol: Use 1 temp buffer instead of allocating 8
+- [THRIFT-3910](https://issues.apache.org/jira/browse/THRIFT-3910) - Do not invoke pip as part of build process
+- [THRIFT-1857](https://issues.apache.org/jira/browse/THRIFT-1857) - Python 3.X Support
+- [THRIFT-1944](https://issues.apache.org/jira/browse/THRIFT-1944) - Binding to zero port
+- [THRIFT-3954](https://issues.apache.org/jira/browse/THRIFT-3954) - Enable the usage of structs called "Object" in Java
+- [THRIFT-3981](https://issues.apache.org/jira/browse/THRIFT-3981) - Enable analyzer strong mode in Dart library
+- [THRIFT-3998](https://issues.apache.org/jira/browse/THRIFT-3998) - Document ability to add custom tags to thrift structs
+- [THRIFT-4006](https://issues.apache.org/jira/browse/THRIFT-4006) - Add a removeEventListener method on TSocket
+
+### New Feature
+- [THRIFT-640](https://issues.apache.org/jira/browse/THRIFT-640) - Support deprecation
+- [THRIFT-948](https://issues.apache.org/jira/browse/THRIFT-948) - SSL socket support for PHP
+- [THRIFT-764](https://issues.apache.org/jira/browse/THRIFT-764) - add Support for Vala language
+- [THRIFT-3046](https://issues.apache.org/jira/browse/THRIFT-3046) - Allow PSR4 class loading for generated classes (PHP)
+- [THRIFT-2113](https://issues.apache.org/jira/browse/THRIFT-2113) - Erlang SSL Socket Support
+- [THRIFT-1482](https://issues.apache.org/jira/browse/THRIFT-1482) - Unix domain socket support under PHP
+- [THRIFT-519](https://issues.apache.org/jira/browse/THRIFT-519) - Support collections of types without having to explicitly define it
+- [THRIFT-468](https://issues.apache.org/jira/browse/THRIFT-468) - Rack Middleware Application for Rails
+- [THRIFT-1708](https://issues.apache.org/jira/browse/THRIFT-1708) - Add event handlers for processor events
+- [THRIFT-3834](https://issues.apache.org/jira/browse/THRIFT-3834) - Erlang namespacing and exception metadata
+- [THRIFT-2510](https://issues.apache.org/jira/browse/THRIFT-2510) - Implement TNonblockingServer's ability to listen on unix domain sockets
+- [THRIFT-3397](https://issues.apache.org/jira/browse/THRIFT-3397) - Implement TProcessorFactory in C# to enable per-client processors
+- [THRIFT-3523](https://issues.apache.org/jira/browse/THRIFT-3523) - XML Generator
+- [THRIFT-3510](https://issues.apache.org/jira/browse/THRIFT-3510) - Add HttpTaskAsyncHandler implementation
+- [THRIFT-3318](https://issues.apache.org/jira/browse/THRIFT-3318) - PHP: SimpleJSONProtocol Implementation
+- [THRIFT-3299](https://issues.apache.org/jira/browse/THRIFT-3299) - Dart language bindings in Thrift
+- [THRIFT-2835](https://issues.apache.org/jira/browse/THRIFT-2835) - Add possibility to distribute generators separately from thrift core, and load them dynamically
+- [THRIFT-184](https://issues.apache.org/jira/browse/THRIFT-184) - Add OSGi Manifest headers to the libthrift java library to be able to use Thrift in the OSGi runtime
+- [THRIFT-141](https://issues.apache.org/jira/browse/THRIFT-141) - If a required field is not present on serialization, throw an exception
+- [THRIFT-1891](https://issues.apache.org/jira/browse/THRIFT-1891) - Add Windows ALPC transport which is right counterpart of Unix domain sockets
+
+### Question
+- [THRIFT-1808](https://issues.apache.org/jira/browse/THRIFT-1808) - The Thrift struct should be considered self-contained?
+- [THRIFT-2895](https://issues.apache.org/jira/browse/THRIFT-2895) - Tutorial cpp
+- [THRIFT-3860](https://issues.apache.org/jira/browse/THRIFT-3860) - Elephant-bird application Test fails for Thrift
+- [THRIFT-3811](https://issues.apache.org/jira/browse/THRIFT-3811) - HTTPS Support for C++ applications
+- [THRIFT-3509](https://issues.apache.org/jira/browse/THRIFT-3509) - "make check" error
+
+### Story
+- [THRIFT-3452](https://issues.apache.org/jira/browse/THRIFT-3452) - .travis.yml: Migrating from legacy to container-based infrastructure
+
+### Sub-task
+- [THRIFT-1811](https://issues.apache.org/jira/browse/THRIFT-1811) - ruby tutorial as part of the regular build
+- [THRIFT-2779](https://issues.apache.org/jira/browse/THRIFT-2779) - PHP TJSONProtocol encode unicode into UCS-4LE which can't be parsed by other language bindings
+- [THRIFT-2110](https://issues.apache.org/jira/browse/THRIFT-2110) - Erlang: Support for Multiplexing Services on any Transport, Protocol and Server
+- [THRIFT-3852](https://issues.apache.org/jira/browse/THRIFT-3852) - A Travis-CI job fails with "write error"
+- [THRIFT-3740](https://issues.apache.org/jira/browse/THRIFT-3740) - Fix haxelib.json classpath
+- [THRIFT-3653](https://issues.apache.org/jira/browse/THRIFT-3653) - incorrect union serialization
+- [THRIFT-3652](https://issues.apache.org/jira/browse/THRIFT-3652) - incorrect serialization of optionals
+- [THRIFT-3655](https://issues.apache.org/jira/browse/THRIFT-3655) - incorrect union serialization
+- [THRIFT-3654](https://issues.apache.org/jira/browse/THRIFT-3654) - incorrect serialization of optionals
+- [THRIFT-3656](https://issues.apache.org/jira/browse/THRIFT-3656) - incorrect serialization of optionals
+- [THRIFT-3699](https://issues.apache.org/jira/browse/THRIFT-3699) - Fix integer limit symbol includes in Python C extension
+- [THRIFT-3693](https://issues.apache.org/jira/browse/THRIFT-3693) - Fix include issue in C++ TSSLSocketInterruptTest on Windows
+- [THRIFT-3694](https://issues.apache.org/jira/browse/THRIFT-3694) - [Windows] Disable tests of a few servers that are not supported
+- [THRIFT-3696](https://issues.apache.org/jira/browse/THRIFT-3696) - Install pip to CentOS Docker images to fix Python builds
+- [THRIFT-3638](https://issues.apache.org/jira/browse/THRIFT-3638) - Fix haxelib.json
+- [THRIFT-3251](https://issues.apache.org/jira/browse/THRIFT-3251) - Add http transport for server to Go lib
+- [THRIFT-2424](https://issues.apache.org/jira/browse/THRIFT-2424) - Recursive Types
+- [THRIFT-2423](https://issues.apache.org/jira/browse/THRIFT-2423) - THeader
+- [THRIFT-2413](https://issues.apache.org/jira/browse/THRIFT-2413) - Python: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
+- [THRIFT-2409](https://issues.apache.org/jira/browse/THRIFT-2409) - Java: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
+- [THRIFT-2412](https://issues.apache.org/jira/browse/THRIFT-2412) - D: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
+- [THRIFT-2411](https://issues.apache.org/jira/browse/THRIFT-2411) - C++: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
+- [THRIFT-2410](https://issues.apache.org/jira/browse/THRIFT-2410) - JavaMe: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
+- [THRIFT-2668](https://issues.apache.org/jira/browse/THRIFT-2668) - TestSuite: detailed result on passed tests by feature
+- [THRIFT-2659](https://issues.apache.org/jira/browse/THRIFT-2659) - python Test Server fails when throwing TException
+- [THRIFT-3398](https://issues.apache.org/jira/browse/THRIFT-3398) - Add CMake build for Haskell library and tests
+- [THRIFT-3396](https://issues.apache.org/jira/browse/THRIFT-3396) - DART: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
+- [THRIFT-3364](https://issues.apache.org/jira/browse/THRIFT-3364) - Fix ruby binary field encoding in TJSONProtocol
+- [THRIFT-3381](https://issues.apache.org/jira/browse/THRIFT-3381) - Fix for misc. codegen issues with THRIFT-2905
+- [THRIFT-3573](https://issues.apache.org/jira/browse/THRIFT-3573) - No rule to make target `../../../test/c_glib/src/.deps/testthrifttest-thrift_test_handler.Po'.
+- [THRIFT-3572](https://issues.apache.org/jira/browse/THRIFT-3572) - "Unable to determine the behavior of a signed right shift"
+- [THRIFT-3542](https://issues.apache.org/jira/browse/THRIFT-3542) - Add length limit support to Java test server
+- [THRIFT-3537](https://issues.apache.org/jira/browse/THRIFT-3537) - Remove the (now obsolete) csharp:asyncctp flag
+- [THRIFT-3532](https://issues.apache.org/jira/browse/THRIFT-3532) - Add configurable string and container read size limit to Python protocols
+- [THRIFT-3531](https://issues.apache.org/jira/browse/THRIFT-3531) - Create cross lang feature test for string and container read length limit
+- [THRIFT-3482](https://issues.apache.org/jira/browse/THRIFT-3482) - Haskell JSON protocol does not encode binary field as Base64
+- [THRIFT-3425](https://issues.apache.org/jira/browse/THRIFT-3425) - Minor fixes + simplification for CentOS Dockerfile
+- [THRIFT-3442](https://issues.apache.org/jira/browse/THRIFT-3442) - Run CMake tests on Appveyor
+- [THRIFT-3409](https://issues.apache.org/jira/browse/THRIFT-3409) - NodeJS binary field issues
+- [THRIFT-3621](https://issues.apache.org/jira/browse/THRIFT-3621) - Fix lib/cpp/test/SecurityTest.cpp to use ephemeral ports
+- [THRIFT-3628](https://issues.apache.org/jira/browse/THRIFT-3628) - Fix lib/cpp/test/TServerIntegrationTest.cpp to use ephemeral ports
+- [THRIFT-3625](https://issues.apache.org/jira/browse/THRIFT-3625) - Kill unused #include "TestPortFixture.h" in lib/cpp/test/TServerTransportTest.cpp.
+- [THRIFT-3646](https://issues.apache.org/jira/browse/THRIFT-3646) - Fix Python extension build warnings
+- [THRIFT-3626](https://issues.apache.org/jira/browse/THRIFT-3626) - Fix lib/cpp/test/TSocketInterruptTest.cpp to use ephemeral ports.
+- [THRIFT-3624](https://issues.apache.org/jira/browse/THRIFT-3624) - Fix lib/cpp/test/TServerSocketTest.cpp to use ephemeral ports
+- [THRIFT-3623](https://issues.apache.org/jira/browse/THRIFT-3623) - Fix Fix cpp/lib/test/TSSLSocketInterruptTest.cpp to use ephemeral ports
+- [THRIFT-3592](https://issues.apache.org/jira/browse/THRIFT-3592) - Add basic test client
+- [THRIFT-3980](https://issues.apache.org/jira/browse/THRIFT-3980) - add TExtendedBinaryProtocol.java
+
+### Task
+- [THRIFT-1801](https://issues.apache.org/jira/browse/THRIFT-1801) - Sync up TApplicationException codes across languages and thrift implementations
+- [THRIFT-1259](https://issues.apache.org/jira/browse/THRIFT-1259) - Automate versioning
+
+### Test
+- [THRIFT-3400](https://issues.apache.org/jira/browse/THRIFT-3400) - Add Erlang to cross test
+- [THRIFT-3504](https://issues.apache.org/jira/browse/THRIFT-3504) - Fix FastbinaryTest.py
+
+### Wish
+- [THRIFT-3923](https://issues.apache.org/jira/browse/THRIFT-3923) - Maybe remove Aereo from the "Powered by" list
+- [THRIFT-2149](https://issues.apache.org/jira/browse/THRIFT-2149) - Add an option to disable the generation of default operators
+
+## 0.9.3.1
+
+Released March 13, 2019 to backport a CVE fix to the popular 0.9.3 release.
+
+### Bug
+- [THRIFT-4506](https://issues.apache.org/jira/browse/THRIFT-4506) - CVE-2018-1320 for Java SASL backported from 0.12.0
+
+## 0.9.3
+
+### Bug
+- [THRIFT-2441](https://issues.apache.org/jira/browse/THRIFT-2441) - Cannot shutdown TThreadedServer when clients are still connected
+- [THRIFT-2465](https://issues.apache.org/jira/browse/THRIFT-2465) - TBinaryProtocolT breaks if copied/moved
+- [THRIFT-2474](https://issues.apache.org/jira/browse/THRIFT-2474) - thrift.h causes a compile failure
+- [THRIFT-2540](https://issues.apache.org/jira/browse/THRIFT-2540) - Running configure from outside the source directory fails
+- [THRIFT-2598](https://issues.apache.org/jira/browse/THRIFT-2598) - Add check for minimum Go version to configure.ac
+- [THRIFT-2647](https://issues.apache.org/jira/browse/THRIFT-2647) - compiler-hs: don't decapitalize field names, do decapitalize argument bindings
+- [THRIFT-2773](https://issues.apache.org/jira/browse/THRIFT-2773) - Generated Java code for 'oneway' methods is incorrect.
+- [THRIFT-2789](https://issues.apache.org/jira/browse/THRIFT-2789) - TNonblockingServer leaks socket FD's under load
+- [THRIFT-2682](https://issues.apache.org/jira/browse/THRIFT-2682) - TThreadedServer leaks per-thread memory
+- [THRIFT-2674](https://issues.apache.org/jira/browse/THRIFT-2674) - JavaScript: declare Accept: and Content-Type: in request
+- [THRIFT-3078](https://issues.apache.org/jira/browse/THRIFT-3078) - TNonblockingServerSocket's logger is not named after TNonblockingServerSocket
+- [THRIFT-3077](https://issues.apache.org/jira/browse/THRIFT-3077) - C++ TFileTransport ignores return code from ftruncate
+- [THRIFT-3067](https://issues.apache.org/jira/browse/THRIFT-3067) - C++ cppcheck performance related warnings
+- [THRIFT-3066](https://issues.apache.org/jira/browse/THRIFT-3066) - C++ TDenseProtocol assert modifies instead of checks
+- [THRIFT-3071](https://issues.apache.org/jira/browse/THRIFT-3071) - bootstrap.sh on Ubuntu 12.04 (Precise) automake error
+- [THRIFT-3069](https://issues.apache.org/jira/browse/THRIFT-3069) - C++ TServerSocket leaks socket on fcntl get or set flags error
+- [THRIFT-3079](https://issues.apache.org/jira/browse/THRIFT-3079) - TNonblockingServerSocket's logger is not named after TNonblockingServerSocket
+- [THRIFT-3080](https://issues.apache.org/jira/browse/THRIFT-3080) - C++ TNonblockingServer connection leak while accept huge number connections.
+- [THRIFT-3086](https://issues.apache.org/jira/browse/THRIFT-3086) - C++ Valgrind Error Cleanup
+- [THRIFT-3085](https://issues.apache.org/jira/browse/THRIFT-3085) - thrift_reconnecting_client never try to reconnect
+- [THRIFT-3123](https://issues.apache.org/jira/browse/THRIFT-3123) - Missing include in compiler/cpp/src/main.h breaks build in some environments
+- [THRIFT-3125](https://issues.apache.org/jira/browse/THRIFT-3125) - Fix the list of exported headers in automake input
+- [THRIFT-3126](https://issues.apache.org/jira/browse/THRIFT-3126) - PHP JSON serializer converts empty or int-indexed maps to lists
+- [THRIFT-3132](https://issues.apache.org/jira/browse/THRIFT-3132) - Properly format date in Java @Generated annotations
+- [THRIFT-3137](https://issues.apache.org/jira/browse/THRIFT-3137) - Travis build hangs after failure
+- [THRIFT-3138](https://issues.apache.org/jira/browse/THRIFT-3138) - "make check" parallel execution is underministic
+- [THRIFT-3139](https://issues.apache.org/jira/browse/THRIFT-3139) - JS library test is flaky
+- [THRIFT-3140](https://issues.apache.org/jira/browse/THRIFT-3140) - ConcurrentModificationException is thrown by JavaScript test server
+- [THRIFT-3124](https://issues.apache.org/jira/browse/THRIFT-3124) - Some signed/unsigned warnings while building compiler
+- [THRIFT-3128](https://issues.apache.org/jira/browse/THRIFT-3128) - Go generated code produces name collisions between services
+- [THRIFT-3146](https://issues.apache.org/jira/browse/THRIFT-3146) - Graphviz generates function name collisions between services
+- [THRIFT-3147](https://issues.apache.org/jira/browse/THRIFT-3147) - Segfault while receiving data
+- [THRIFT-3148](https://issues.apache.org/jira/browse/THRIFT-3148) - Markdown links to coding_standards are dead
+- [THRIFT-3090](https://issues.apache.org/jira/browse/THRIFT-3090) - cmake build is broken on MacOSX
+- [THRIFT-3097](https://issues.apache.org/jira/browse/THRIFT-3097) - cmake targets unconditionally depend on optional libraries
+- [THRIFT-3094](https://issues.apache.org/jira/browse/THRIFT-3094) - master as of 2015-APR-13 fails -DBOOST_THREADS cmake build
+- [THRIFT-3099](https://issues.apache.org/jira/browse/THRIFT-3099) - cmake build is broken on FreeBSD
+- [THRIFT-3089](https://issues.apache.org/jira/browse/THRIFT-3089) - Assigning default ENUM values results in non-compilable java code if java namespace is not defined
+- [THRIFT-3093](https://issues.apache.org/jira/browse/THRIFT-3093) - mingw compile fixes for c++ library 0.9.2
+- [THRIFT-3098](https://issues.apache.org/jira/browse/THRIFT-3098) - Thrift does not pretty print binary typedefs the way it does binary fields
+- [THRIFT-3091](https://issues.apache.org/jira/browse/THRIFT-3091) - c_glib service method should return result from handler method
+- [THRIFT-3088](https://issues.apache.org/jira/browse/THRIFT-3088) - TThreadPoolServer with Sasl auth may leak CLOSE_WAIT socket
+- [THRIFT-3109](https://issues.apache.org/jira/browse/THRIFT-3109) - Cross test log file cannot be browsed when served in HTTP server
+- [THRIFT-3113](https://issues.apache.org/jira/browse/THRIFT-3113) - m4 C++11 macro issue
+- [THRIFT-3105](https://issues.apache.org/jira/browse/THRIFT-3105) - C++ libthriftnb library on Windows build failure
+- [THRIFT-3115](https://issues.apache.org/jira/browse/THRIFT-3115) - Uncompileable code due to name collision with predefined used types
+- [THRIFT-3117](https://issues.apache.org/jira/browse/THRIFT-3117) - Java TSSLTransportFactory can't load certificates within JAR archive
+- [THRIFT-3102](https://issues.apache.org/jira/browse/THRIFT-3102) - could not make check for Go Library
+- [THRIFT-3120](https://issues.apache.org/jira/browse/THRIFT-3120) - Minor spelling errors and an outdated URL
+- [THRIFT-3121](https://issues.apache.org/jira/browse/THRIFT-3121) - Librt does not exist on OS X
+- [THRIFT-3152](https://issues.apache.org/jira/browse/THRIFT-3152) - Compiler error on Mac OSX (missing #include <cstdlib>)
+- [THRIFT-3162](https://issues.apache.org/jira/browse/THRIFT-3162) - make fails for dmd 2.067
+- [THRIFT-3164](https://issues.apache.org/jira/browse/THRIFT-3164) - Thrift C++ library SSL socket by default allows for unsecure SSLv3 negotiation
+- [THRIFT-3168](https://issues.apache.org/jira/browse/THRIFT-3168) - Fix Maven POM
+- [THRIFT-3170](https://issues.apache.org/jira/browse/THRIFT-3170) - Initialism code in the Go compiler causes chaos
+- [THRIFT-3169](https://issues.apache.org/jira/browse/THRIFT-3169) - Do not export thrift.TestStruct and thrift.TestEnum in thrift Go library
+- [THRIFT-3191](https://issues.apache.org/jira/browse/THRIFT-3191) - Perl compiler does not add support for unexpected exception handling
+- [THRIFT-3178](https://issues.apache.org/jira/browse/THRIFT-3178) - glib C does not compile
+- [THRIFT-3189](https://issues.apache.org/jira/browse/THRIFT-3189) - Perl ServerSocket should allow a specific interface to be listened to
+- [THRIFT-3252](https://issues.apache.org/jira/browse/THRIFT-3252) - Missing TConcurrentClientSyncInfo.h in cpp Makefile, so doesn't install
+- [THRIFT-3255](https://issues.apache.org/jira/browse/THRIFT-3255) - Thrift generator doesn't exclude 'package' keyword for thrift property names breaking java builds
+- [THRIFT-3260](https://issues.apache.org/jira/browse/THRIFT-3260) - multiple warnings in c_glib tutorial
+- [THRIFT-3256](https://issues.apache.org/jira/browse/THRIFT-3256) - Some D test timings are too aggressive for slow machines
+- [THRIFT-3257](https://issues.apache.org/jira/browse/THRIFT-3257) - warning: extra tokens at end of #endif directive
+- [THRIFT-3184](https://issues.apache.org/jira/browse/THRIFT-3184) - Thrift Go leaves file descriptors open
+- [THRIFT-3203](https://issues.apache.org/jira/browse/THRIFT-3203) - DOAP - please fix "Ocaml" => "OCaml"
+- [THRIFT-3210](https://issues.apache.org/jira/browse/THRIFT-3210) - (uncompileable) code generated for server events while are events not enabled
+- [THRIFT-3215](https://issues.apache.org/jira/browse/THRIFT-3215) - TJSONProtocol '(c++) uses "throw new" to throw exceptions instead of "throw"
+- [THRIFT-3202](https://issues.apache.org/jira/browse/THRIFT-3202) - Allow HSHAServer to configure min and max worker threads separately.
+- [THRIFT-3205](https://issues.apache.org/jira/browse/THRIFT-3205) - TCompactProtocol return a wrong error when the io.EOF happens
+- [THRIFT-3209](https://issues.apache.org/jira/browse/THRIFT-3209) - LGPL mentioned in license file
+- [THRIFT-3197](https://issues.apache.org/jira/browse/THRIFT-3197) - keepAliveTime is hard coded as 60 sec in TThreadPoolServer
+- [THRIFT-3196](https://issues.apache.org/jira/browse/THRIFT-3196) - Misspelling in lua TBinaryProtocol (stirctWrite => strictWrite)
+- [THRIFT-3198](https://issues.apache.org/jira/browse/THRIFT-3198) - Allow construction of TTransportFactory with a specified maxLength
+- [THRIFT-3192](https://issues.apache.org/jira/browse/THRIFT-3192) - Go import paths changed in 1.4, and expired June 1
+- [THRIFT-3271](https://issues.apache.org/jira/browse/THRIFT-3271) - Could not find or load main class configtest_ax_javac_and_java on some non-english systems
+- [THRIFT-3273](https://issues.apache.org/jira/browse/THRIFT-3273) - c_glib: Generated code tries to convert between function and void pointers
+- [THRIFT-3264](https://issues.apache.org/jira/browse/THRIFT-3264) - Fix Erlang 16 namespaced types
+- [THRIFT-3270](https://issues.apache.org/jira/browse/THRIFT-3270) - reusing TNonblockingServer::TConnection cause dirty TSocket
+- [THRIFT-3267](https://issues.apache.org/jira/browse/THRIFT-3267) - c_glib: "Critical" failure during unit tests
+- [THRIFT-3277](https://issues.apache.org/jira/browse/THRIFT-3277) - THttpClient leaks connections if it's used for multiple requests
+- [THRIFT-3278](https://issues.apache.org/jira/browse/THRIFT-3278) - NodeJS: Fix exception stack traces and names
+- [THRIFT-3279](https://issues.apache.org/jira/browse/THRIFT-3279) - Fix a bug in retry_max_delay (NodeJS)
+- [THRIFT-3280](https://issues.apache.org/jira/browse/THRIFT-3280) - Initialize retry variables on construction
+- [THRIFT-3283](https://issues.apache.org/jira/browse/THRIFT-3283) - c_glib: Tutorial server always exits with warning
+- [THRIFT-3284](https://issues.apache.org/jira/browse/THRIFT-3284) - c_glib: Empty service produces unused-variable warning
+- [THRIFT-1925](https://issues.apache.org/jira/browse/THRIFT-1925) - c_glib generated code does not compile
+- [THRIFT-1849](https://issues.apache.org/jira/browse/THRIFT-1849) - after transport->open() opens isOpen returns true and next open() goes thru when it shall not
+- [THRIFT-1866](https://issues.apache.org/jira/browse/THRIFT-1866) - java compiler generates non-compiling code with const's defined in a thrift when name includes non-identifier chars
+- [THRIFT-1938](https://issues.apache.org/jira/browse/THRIFT-1938) - FunctionRunner.h -- uses wrong path for Thread.h when installed
+- [THRIFT-1844](https://issues.apache.org/jira/browse/THRIFT-1844) - Password string not cleared
+- [THRIFT-2004](https://issues.apache.org/jira/browse/THRIFT-2004) - Thrift::Union violates :== method contract and crashes
+- [THRIFT-2073](https://issues.apache.org/jira/browse/THRIFT-2073) - Thrift C++ THttpClient error: cannot refill buffer
+- [THRIFT-2127](https://issues.apache.org/jira/browse/THRIFT-2127) - Autoconf scripting does not properly account for cross-compile
+- [THRIFT-2180](https://issues.apache.org/jira/browse/THRIFT-2180) - Integer types issues in Cocoa lib on ARM64
+- [THRIFT-2189](https://issues.apache.org/jira/browse/THRIFT-2189) - Go needs "isset" to fully support "union" type (and optionals)
+- [THRIFT-2192](https://issues.apache.org/jira/browse/THRIFT-2192) - autotools on Redhat based systems
+- [THRIFT-2546](https://issues.apache.org/jira/browse/THRIFT-2546) - cross language tests fails at 'TestMultiException' when using nodejs server
+- [THRIFT-2547](https://issues.apache.org/jira/browse/THRIFT-2547) - nodejs servers and clients fails to connect with cpp using compact protocol
+- [THRIFT-2548](https://issues.apache.org/jira/browse/THRIFT-2548) - Nodejs servers and clients does not work properly with -ssl
+- [THRIFT-1471](https://issues.apache.org/jira/browse/THRIFT-1471) - toString() does not print ByteBuffer values when nested in a List
+- [THRIFT-1201](https://issues.apache.org/jira/browse/THRIFT-1201) - getaddrinfo resource leak
+- [THRIFT-615](https://issues.apache.org/jira/browse/THRIFT-615) - TThreadPoolServer doesn't call task_done after pulling tasks from it's clients queue
+- [THRIFT-162](https://issues.apache.org/jira/browse/THRIFT-162) - Thrift structures are unhashable, preventing them from being used as set elements
+- [THRIFT-810](https://issues.apache.org/jira/browse/THRIFT-810) - Crashed client on TSocket::close under loads
+- [THRIFT-557](https://issues.apache.org/jira/browse/THRIFT-557) - charset problem with file Autogenerated by Thrift
+- [THRIFT-233](https://issues.apache.org/jira/browse/THRIFT-233) - IDL doesn't support negative hex literals
+- [THRIFT-1649](https://issues.apache.org/jira/browse/THRIFT-1649) - contrib/zeromq does not build in 0.8.0
+- [THRIFT-1642](https://issues.apache.org/jira/browse/THRIFT-1642) - Miscalculation lead to throw unexpected "TTransportException::TIMED_OUT"(or called "EAGAIN (timed out)") exception
+- [THRIFT-1587](https://issues.apache.org/jira/browse/THRIFT-1587) - TSocket::setRecvTimeout error
+- [THRIFT-1248](https://issues.apache.org/jira/browse/THRIFT-1248) - pointer subtraction in TMemoryBuffer relies on undefined behavior
+- [THRIFT-1774](https://issues.apache.org/jira/browse/THRIFT-1774) - Sasl Transport client would hang when trying to connect non-sasl transport server
+- [THRIFT-1754](https://issues.apache.org/jira/browse/THRIFT-1754) - RangeError in buffer handling
+- [THRIFT-1618](https://issues.apache.org/jira/browse/THRIFT-1618) - static structMap in FieldMetaData is not thread safe and can lead to deadlocks
+- [THRIFT-2335](https://issues.apache.org/jira/browse/THRIFT-2335) - thrift incompatibility with py:tornado as server, java as client
+- [THRIFT-2803](https://issues.apache.org/jira/browse/THRIFT-2803) - TCP_DEFER_ACCEPT not supported with domain sockets
+- [THRIFT-2799](https://issues.apache.org/jira/browse/THRIFT-2799) - Build Problem(s): ld: library not found for -l:libboost_unit_test_framework.a
+- [THRIFT-2801](https://issues.apache.org/jira/browse/THRIFT-2801) - C++ test suite compilation warnings
+- [THRIFT-2802](https://issues.apache.org/jira/browse/THRIFT-2802) - C++ tutorial compilation warnings
+- [THRIFT-2795](https://issues.apache.org/jira/browse/THRIFT-2795) - thrift_binary_protocol.c: 'dereferencing type-punned pointer will break strict-aliasing rules'
+- [THRIFT-2817](https://issues.apache.org/jira/browse/THRIFT-2817) - TSimpleJSONProtocol reads beyond end of message
+- [THRIFT-2826](https://issues.apache.org/jira/browse/THRIFT-2826) - html:standalone sometimes ignored
+- [THRIFT-2829](https://issues.apache.org/jira/browse/THRIFT-2829) - Support haxelib installation via github
+- [THRIFT-2828](https://issues.apache.org/jira/browse/THRIFT-2828) - slightly wrong help screen indent
+- [THRIFT-2831](https://issues.apache.org/jira/browse/THRIFT-2831) - Removes dead code in web_server.js introduced in THRIFT-2819
+- [THRIFT-2823](https://issues.apache.org/jira/browse/THRIFT-2823) - All JS-tests are failing when run with grunt test
+- [THRIFT-2827](https://issues.apache.org/jira/browse/THRIFT-2827) - Thrift 0.9.2 fails to compile on Yosemite due to tr1/functional include in ProcessorTest.cpp
+- [THRIFT-2843](https://issues.apache.org/jira/browse/THRIFT-2843) - Automake configure.ac has possible typo related to Java
+- [THRIFT-2813](https://issues.apache.org/jira/browse/THRIFT-2813) - multiple haxe library fixes/improvements
+- [THRIFT-2825](https://issues.apache.org/jira/browse/THRIFT-2825) - Supplying unicode to python Thrift client can cause next request arguments to get overwritten
+- [THRIFT-2840](https://issues.apache.org/jira/browse/THRIFT-2840) - Cabal file points to LICENSE file outside the path of the Haskell project.
+- [THRIFT-2818](https://issues.apache.org/jira/browse/THRIFT-2818) - Trailing commas in array
+- [THRIFT-2830](https://issues.apache.org/jira/browse/THRIFT-2830) - Clean up ant warnings in tutorial dir
+- [THRIFT-2842](https://issues.apache.org/jira/browse/THRIFT-2842) - Erlang thrift client has infinite timeout
+- [THRIFT-2810](https://issues.apache.org/jira/browse/THRIFT-2810) - Do not leave the underlying ServerSocket open if construction of TServerSocket fails
+- [THRIFT-2812](https://issues.apache.org/jira/browse/THRIFT-2812) - Go server adding redundant buffering layer
+- [THRIFT-2839](https://issues.apache.org/jira/browse/THRIFT-2839) - TFramedTransport read bug
+- [THRIFT-2844](https://issues.apache.org/jira/browse/THRIFT-2844) - Nodejs support broken when running under Browserify
+- [THRIFT-2814](https://issues.apache.org/jira/browse/THRIFT-2814) - args/result classes not found when no namespace is set
+- [THRIFT-2847](https://issues.apache.org/jira/browse/THRIFT-2847) - function IfValue() is a duplicate of System.StrUtils.IfThen
+- [THRIFT-2848](https://issues.apache.org/jira/browse/THRIFT-2848) - certain Delphi tests do not build if TypeRegistry is used
+- [THRIFT-2854](https://issues.apache.org/jira/browse/THRIFT-2854) - Go Struct writer and reader looses important error information
+- [THRIFT-2858](https://issues.apache.org/jira/browse/THRIFT-2858) - Enable header field case insensitive match in THttpServer
+- [THRIFT-2857](https://issues.apache.org/jira/browse/THRIFT-2857) - C# generator creates uncompilable code for struct constants
+- [THRIFT-2860](https://issues.apache.org/jira/browse/THRIFT-2860) - Delphi server closes connection on unexpected exceptions
+- [THRIFT-2868](https://issues.apache.org/jira/browse/THRIFT-2868) - Enhance error handling in the Go client
+- [THRIFT-2879](https://issues.apache.org/jira/browse/THRIFT-2879) - TMemoryBuffer: using lua string in wrong way
+- [THRIFT-2851](https://issues.apache.org/jira/browse/THRIFT-2851) - Remove strange public Peek() from Go transports
+- [THRIFT-2852](https://issues.apache.org/jira/browse/THRIFT-2852) - Better Open/IsOpen/Close behavior for StreamTransport.
+- [THRIFT-2871](https://issues.apache.org/jira/browse/THRIFT-2871) - Missing semicolon in thrift.js
+- [THRIFT-2872](https://issues.apache.org/jira/browse/THRIFT-2872) - ThreadManager deadlock for task expiration
+- [THRIFT-2881](https://issues.apache.org/jira/browse/THRIFT-2881) - Handle errors from Accept() correctly
+- [THRIFT-2849](https://issues.apache.org/jira/browse/THRIFT-2849) - Spell errors reported by codespell tool
+- [THRIFT-2870](https://issues.apache.org/jira/browse/THRIFT-2870) - C++ TJSONProtocol using locale dependent formatting
+- [THRIFT-2882](https://issues.apache.org/jira/browse/THRIFT-2882) - Lua Generator: using string.len funtion to get struct(map,list,set) size
+- [THRIFT-2864](https://issues.apache.org/jira/browse/THRIFT-2864) - JSON generator missing from Visual Studio build project
+- [THRIFT-2878](https://issues.apache.org/jira/browse/THRIFT-2878) - Go validation support of required fields
+- [THRIFT-2873](https://issues.apache.org/jira/browse/THRIFT-2873) - TPipe and TPipeServer don't compile on Windows with UNICODE enabled
+- [THRIFT-2888](https://issues.apache.org/jira/browse/THRIFT-2888) - import of <limits> is missing in JSON generator
+- [THRIFT-2900](https://issues.apache.org/jira/browse/THRIFT-2900) - Python THttpClient does not reset socket timeout on exception
+- [THRIFT-2907](https://issues.apache.org/jira/browse/THRIFT-2907) - 'ntohll' macro redefined
+- [THRIFT-2884](https://issues.apache.org/jira/browse/THRIFT-2884) - Map does not serialize correctly for JSON protocol in Go library
+- [THRIFT-2887](https://issues.apache.org/jira/browse/THRIFT-2887) - --with-openssl configure flag is ignored
+- [THRIFT-2894](https://issues.apache.org/jira/browse/THRIFT-2894) - PHP json serializer skips maps with int/bool keys
+- [THRIFT-2904](https://issues.apache.org/jira/browse/THRIFT-2904) - json_protocol_test.go fails
+- [THRIFT-2906](https://issues.apache.org/jira/browse/THRIFT-2906) - library not found for -l:libboost_unit_test_framework.a
+- [THRIFT-2890](https://issues.apache.org/jira/browse/THRIFT-2890) - binary data may lose bytes with JSON transport under specific circumstances
+- [THRIFT-2891](https://issues.apache.org/jira/browse/THRIFT-2891) - binary data may cause a failure with JSON transport under specific circumstances
+- [THRIFT-2901](https://issues.apache.org/jira/browse/THRIFT-2901) - Fix for generated TypeScript functions + indentation of JavaScript maps
+- [THRIFT-2916](https://issues.apache.org/jira/browse/THRIFT-2916) - make check fails for D language
+- [THRIFT-2918](https://issues.apache.org/jira/browse/THRIFT-2918) - Race condition in Python TProcessPoolServer test
+- [THRIFT-2920](https://issues.apache.org/jira/browse/THRIFT-2920) - Erlang Thrift test uses wrong IDL file
+- [THRIFT-2922](https://issues.apache.org/jira/browse/THRIFT-2922) - $TRIAL is used with Python tests but not tested accordingly
+- [THRIFT-2912](https://issues.apache.org/jira/browse/THRIFT-2912) - Autotool build for C++ Qt library is invalid
+- [THRIFT-2914](https://issues.apache.org/jira/browse/THRIFT-2914) - explicit dependency to Lua5.2 fails on some systems
+- [THRIFT-2910](https://issues.apache.org/jira/browse/THRIFT-2910) - libevent is not really optional
+- [THRIFT-2911](https://issues.apache.org/jira/browse/THRIFT-2911) - fix c++ version zeromq transport, the old version cannot work
+- [THRIFT-2915](https://issues.apache.org/jira/browse/THRIFT-2915) - Lua generator missing from Visual Studio build project
+- [THRIFT-2917](https://issues.apache.org/jira/browse/THRIFT-2917) - "make clean" breaks test/c_glib
+- [THRIFT-2919](https://issues.apache.org/jira/browse/THRIFT-2919) - Haxe test server timeout too large
+- [THRIFT-2923](https://issues.apache.org/jira/browse/THRIFT-2923) - JavaScript client assumes a message being written
+- [THRIFT-2924](https://issues.apache.org/jira/browse/THRIFT-2924) - TNonblockingServer crashes when user-provided event_base is used
+- [THRIFT-2925](https://issues.apache.org/jira/browse/THRIFT-2925) - CMake build does not work with OpenSSL nor anything installed in non-system location
+- [THRIFT-2931](https://issues.apache.org/jira/browse/THRIFT-2931) - Access to undeclared static property: Thrift\Protocol\TProtocol::$TBINARYPROTOCOLACCELERATED
+- [THRIFT-2893](https://issues.apache.org/jira/browse/THRIFT-2893) - CMake build fails with boost thread or std thread
+- [THRIFT-2902](https://issues.apache.org/jira/browse/THRIFT-2902) - Generated c_glib code does not compile with clang
+- [THRIFT-2903](https://issues.apache.org/jira/browse/THRIFT-2903) - Qt4 library built with CMake does not work
+- [THRIFT-2942](https://issues.apache.org/jira/browse/THRIFT-2942) - CSharp generate invalid code for property named read or write
+- [THRIFT-2932](https://issues.apache.org/jira/browse/THRIFT-2932) - Node.js Thrift connection libraries throw Exceptions into event emitter
+- [THRIFT-2933](https://issues.apache.org/jira/browse/THRIFT-2933) - v0.9.2: doubles encoded in node with compact protocol cannot be decoded by python
+- [THRIFT-2934](https://issues.apache.org/jira/browse/THRIFT-2934) - createServer signature mismatch
+- [THRIFT-2981](https://issues.apache.org/jira/browse/THRIFT-2981) - IDL with no namespace produces unparsable PHP
+- [THRIFT-2999](https://issues.apache.org/jira/browse/THRIFT-2999) - Addition of .gitattributes text auto in THRIFT-2724 causes modified files on checkout
+- [THRIFT-2949](https://issues.apache.org/jira/browse/THRIFT-2949) - typo in compiler/cpp/README.md
+- [THRIFT-2957](https://issues.apache.org/jira/browse/THRIFT-2957) - warning: source file %s is in a subdirectory, but option 'subdir-objects' is disabled
+- [THRIFT-2953](https://issues.apache.org/jira/browse/THRIFT-2953) - TNamedPipeServerTransport is not Stop()able
+- [THRIFT-2962](https://issues.apache.org/jira/browse/THRIFT-2962) - Docker Thrift env for development and testing
+- [THRIFT-2971](https://issues.apache.org/jira/browse/THRIFT-2971) - C++ test and tutorial parallel build is unstable
+- [THRIFT-2972](https://issues.apache.org/jira/browse/THRIFT-2972) - Missing backslash in lib/cpp/test/Makefile.am
+- [THRIFT-2951](https://issues.apache.org/jira/browse/THRIFT-2951) - Fix Erlang name conflict test
+- [THRIFT-2955](https://issues.apache.org/jira/browse/THRIFT-2955) - Using list of typedefs does not compile on Go
+- [THRIFT-2960](https://issues.apache.org/jira/browse/THRIFT-2960) - namespace regression for Ruby
+- [THRIFT-2959](https://issues.apache.org/jira/browse/THRIFT-2959) - nodejs: fix binary unit tests
+- [THRIFT-2966](https://issues.apache.org/jira/browse/THRIFT-2966) - nodejs: Fix bad references to TProtocolException and TProtocolExceptionType
+- [THRIFT-2970](https://issues.apache.org/jira/browse/THRIFT-2970) - grunt-jsdoc fails due to dependency issues
+- [THRIFT-3001](https://issues.apache.org/jira/browse/THRIFT-3001) - C# Equals fails for binary fields (byte[])
+- [THRIFT-3003](https://issues.apache.org/jira/browse/THRIFT-3003) - Missing LICENSE file prevents package from being installed
+- [THRIFT-3008](https://issues.apache.org/jira/browse/THRIFT-3008) - Node.js server does not fully support exception
+- [THRIFT-3007](https://issues.apache.org/jira/browse/THRIFT-3007) - Travis build is broken because of directory conflict
+- [THRIFT-3009](https://issues.apache.org/jira/browse/THRIFT-3009) - TSSLSocket does not use the correct hostname (breaks certificate checks)
+- [THRIFT-3011](https://issues.apache.org/jira/browse/THRIFT-3011) - C# test server testException() not implemented according to specs
+- [THRIFT-3012](https://issues.apache.org/jira/browse/THRIFT-3012) - Timing problems in NamedPipe implementation due to unnecessary open/close
+- [THRIFT-3019](https://issues.apache.org/jira/browse/THRIFT-3019) - Golang generator missing docstring for structs
+- [THRIFT-3021](https://issues.apache.org/jira/browse/THRIFT-3021) - Service remote tool does not import stub package with package prefix
+- [THRIFT-3026](https://issues.apache.org/jira/browse/THRIFT-3026) - TMultiplexedProcessor does not have a constructor
+- [THRIFT-3028](https://issues.apache.org/jira/browse/THRIFT-3028) - Regression caused by THRIFT-2180
+- [THRIFT-3017](https://issues.apache.org/jira/browse/THRIFT-3017) - order of map key/value types incorrect for one CTOR
+- [THRIFT-3020](https://issues.apache.org/jira/browse/THRIFT-3020) - Cannot compile thrift as C++03
+- [THRIFT-3024](https://issues.apache.org/jira/browse/THRIFT-3024) - User-Agent "BattleNet" used in some Thrift library files
+- [THRIFT-3047](https://issues.apache.org/jira/browse/THRIFT-3047) - Uneven calls to indent_up and indent_down in Cocoa generator
+- [THRIFT-3048](https://issues.apache.org/jira/browse/THRIFT-3048) - NodeJS decoding of I64 is inconsistent across protocols
+- [THRIFT-3043](https://issues.apache.org/jira/browse/THRIFT-3043) - go compiler generator uses non C++98 code
+- [THRIFT-3044](https://issues.apache.org/jira/browse/THRIFT-3044) - Docker README.md paths to Dockerfiles are incorrect
+- [THRIFT-3040](https://issues.apache.org/jira/browse/THRIFT-3040) - bower.json wrong "main" path
+- [THRIFT-3051](https://issues.apache.org/jira/browse/THRIFT-3051) - Go Thrift generator creates bad go code
+- [THRIFT-3057](https://issues.apache.org/jira/browse/THRIFT-3057) - Java compiler build is broken
+- [THRIFT-3061](https://issues.apache.org/jira/browse/THRIFT-3061) - C++ TSSLSocket shutdown delay/vulnerability
+- [THRIFT-3062](https://issues.apache.org/jira/browse/THRIFT-3062) - C++ TServerSocket invalid port number (over 999999) causes stack corruption
+- [THRIFT-3065](https://issues.apache.org/jira/browse/THRIFT-3065) - Update libthrift dependencies (slf4j, httpcore, httpclient)
+- [THRIFT-3244](https://issues.apache.org/jira/browse/THRIFT-3244) - TypeScript: fix namespace of included types
+- [THRIFT-3246](https://issues.apache.org/jira/browse/THRIFT-3246) - Reduce the number of trivial warnings in Windows C++ CMake builds
+- [THRIFT-3224](https://issues.apache.org/jira/browse/THRIFT-3224) - Fix TNamedPipeServer unpredictable behavior on accept
+- [THRIFT-3230](https://issues.apache.org/jira/browse/THRIFT-3230) - Python compiler generates wrong code if there is function throwing a typedef of exception with another namespace
+- [THRIFT-3236](https://issues.apache.org/jira/browse/THRIFT-3236) - MaxSkipDepth never checked
+- [THRIFT-3239](https://issues.apache.org/jira/browse/THRIFT-3239) - Limit recursion depth
+- [THRIFT-3241](https://issues.apache.org/jira/browse/THRIFT-3241) - fatal error: runtime: cannot map pages in arena address space
+- [THRIFT-3242](https://issues.apache.org/jira/browse/THRIFT-3242) - OSGi Import-Package directive is missing the Apache HTTP packages
+- [THRIFT-3234](https://issues.apache.org/jira/browse/THRIFT-3234) - Limit recursion depth
+- [THRIFT-3222](https://issues.apache.org/jira/browse/THRIFT-3222) - TypeScript: Generated Enums are quoted
+- [THRIFT-3229](https://issues.apache.org/jira/browse/THRIFT-3229) - unexpected Timeout exception when desired bytes are only partially available
+- [THRIFT-3231](https://issues.apache.org/jira/browse/THRIFT-3231) - CPP: Limit recursion depth to 64
+- [THRIFT-3235](https://issues.apache.org/jira/browse/THRIFT-3235) - Limit recursion depth
+- [THRIFT-3175](https://issues.apache.org/jira/browse/THRIFT-3175) - fastbinary.c python deserialize can cause huge allocations from garbage
+- [THRIFT-3176](https://issues.apache.org/jira/browse/THRIFT-3176) - Union incorrectly implements ==
+- [THRIFT-3177](https://issues.apache.org/jira/browse/THRIFT-3177) - Fails to run rake test
+- [THRIFT-3180](https://issues.apache.org/jira/browse/THRIFT-3180) - lua plugin: framed transport do not work
+- [THRIFT-3179](https://issues.apache.org/jira/browse/THRIFT-3179) - lua plugin cant connect to remote server because function l_socket_create_and_connect always bind socket to localhost
+- [THRIFT-3248](https://issues.apache.org/jira/browse/THRIFT-3248) - TypeScript: additional comma in method signature without parameters
+- [THRIFT-3302](https://issues.apache.org/jira/browse/THRIFT-3302) - Go JSON protocol should encode Thrift byte type as signed integer string
+- [THRIFT-3297](https://issues.apache.org/jira/browse/THRIFT-3297) - c_glib: an abstract base class is not generated
+- [THRIFT-3294](https://issues.apache.org/jira/browse/THRIFT-3294) - TZlibTransport for Java does not write data correctly
+- [THRIFT-3296](https://issues.apache.org/jira/browse/THRIFT-3296) - Go cross test does not conform to spec
+- [THRIFT-3295](https://issues.apache.org/jira/browse/THRIFT-3295) - C# library does not build on Mono 4.0.2.5 or later
+- [THRIFT-3293](https://issues.apache.org/jira/browse/THRIFT-3293) - JavaScript: null values turn into empty structs in constructor
+- [THRIFT-3310](https://issues.apache.org/jira/browse/THRIFT-3310) - lib/erl/README.md has incorrect formatting
+- [THRIFT-3319](https://issues.apache.org/jira/browse/THRIFT-3319) - CSharp tutorial will not build using the *.sln
+- [THRIFT-3335](https://issues.apache.org/jira/browse/THRIFT-3335) - Ruby server does not handle processor exception
+- [THRIFT-3338](https://issues.apache.org/jira/browse/THRIFT-3338) - Stray underscore in generated go when service name starts with "New"
+- [THRIFT-3324](https://issues.apache.org/jira/browse/THRIFT-3324) - Update Go Docs for pulling all packages
+- [THRIFT-3345](https://issues.apache.org/jira/browse/THRIFT-3345) - Clients blocked indefinitely when a java.lang.Error is thrown
+- [THRIFT-3332](https://issues.apache.org/jira/browse/THRIFT-3332) - make dist fails on clean build
+- [THRIFT-3326](https://issues.apache.org/jira/browse/THRIFT-3326) - Tests do not compile under *BSD
+- [THRIFT-3334](https://issues.apache.org/jira/browse/THRIFT-3334) - Markdown notation of protocol spec is malformed
+- [THRIFT-3331](https://issues.apache.org/jira/browse/THRIFT-3331) - warning: ‘etype’ may be used uninitialized in this function
+- [THRIFT-3349](https://issues.apache.org/jira/browse/THRIFT-3349) - Python server does not handle processor exception
+- [THRIFT-3343](https://issues.apache.org/jira/browse/THRIFT-3343) - Fix haskell README
+- [THRIFT-3340](https://issues.apache.org/jira/browse/THRIFT-3340) - Python: enable json tests again
+- [THRIFT-3311](https://issues.apache.org/jira/browse/THRIFT-3311) - Top level README.md has incorrect formmating
+- [THRIFT-2936](https://issues.apache.org/jira/browse/THRIFT-2936) - Minor memory leak in SSL
+- [THRIFT-3290](https://issues.apache.org/jira/browse/THRIFT-3290) - Using from in variable names causes the generated Python code to have errors
+- [THRIFT-3225](https://issues.apache.org/jira/browse/THRIFT-3225) - Fix TPipeServer unpredictable behavior on interrupt()
+- [THRIFT-3354](https://issues.apache.org/jira/browse/THRIFT-3354) - Fix word-extraction substr bug in initialism code
+- [THRIFT-2006](https://issues.apache.org/jira/browse/THRIFT-2006) - TBinaryProtocol message header call name length is not validated and can be used to core the server
+- [THRIFT-3329](https://issues.apache.org/jira/browse/THRIFT-3329) - C++ library unit tests don't compile against the new boost-1.59 unit test framework
+- [THRIFT-2630](https://issues.apache.org/jira/browse/THRIFT-2630) - windows7 64bit pc. ipv4 and ipv6 pc.can't use
+- [THRIFT-3336](https://issues.apache.org/jira/browse/THRIFT-3336) - Thrift generated streaming operators added in 0.9.2 cannot be overridden
+- [THRIFT-2681](https://issues.apache.org/jira/browse/THRIFT-2681) - Core of unwind_cleanup
+- [THRIFT-3317](https://issues.apache.org/jira/browse/THRIFT-3317) - cpp namespace org.apache issue appears in 0.9
+
+### Documentation
+- [THRIFT-3286](https://issues.apache.org/jira/browse/THRIFT-3286) - Apache Ant is a necessary dependency
+
+### Improvement
+- [THRIFT-227](https://issues.apache.org/jira/browse/THRIFT-227) - Byte[] in collections aren't pretty printed like regular binary fields
+- [THRIFT-2744](https://issues.apache.org/jira/browse/THRIFT-2744) - Vagrantfile for Centos 6.5
+- [THRIFT-2644](https://issues.apache.org/jira/browse/THRIFT-2644) - Haxe support
+- [THRIFT-2756](https://issues.apache.org/jira/browse/THRIFT-2756) - register Media Type @ IANA
+- [THRIFT-3076](https://issues.apache.org/jira/browse/THRIFT-3076) - Compatibility with Haxe 3.2.0
+- [THRIFT-3081](https://issues.apache.org/jira/browse/THRIFT-3081) - C++ Consolidate client processing loops in TServers
+- [THRIFT-3083](https://issues.apache.org/jira/browse/THRIFT-3083) - C++ Consolidate server processing loops in TSimpleServer, TThreadedServer, TThreadPoolServer
+- [THRIFT-3084](https://issues.apache.org/jira/browse/THRIFT-3084) - C++ add concurrent client limit to threaded servers
+- [THRIFT-3074](https://issues.apache.org/jira/browse/THRIFT-3074) - Add compiler/cpp/lex.yythriftl.cc to gitignore.
+- [THRIFT-3134](https://issues.apache.org/jira/browse/THRIFT-3134) - Remove use of deprecated "phantom.args"
+- [THRIFT-3133](https://issues.apache.org/jira/browse/THRIFT-3133) - Allow "make cross" and "make precross" to run without building all languages
+- [THRIFT-3142](https://issues.apache.org/jira/browse/THRIFT-3142) - Make JavaScript use downloaded libraries
+- [THRIFT-3141](https://issues.apache.org/jira/browse/THRIFT-3141) - Improve logging of JavaScript test
+- [THRIFT-3144](https://issues.apache.org/jira/browse/THRIFT-3144) - Proposal: make String representation of enums in generated go code less verbose
+- [THRIFT-3130](https://issues.apache.org/jira/browse/THRIFT-3130) - Remove the last vestiges of THRIFT_OVERLOAD_IF from THRIFT-1316
+- [THRIFT-3131](https://issues.apache.org/jira/browse/THRIFT-3131) - Consolidate suggested import path for go thrift library to git.apache.org in docs and code
+- [THRIFT-3092](https://issues.apache.org/jira/browse/THRIFT-3092) - Generated Haskell types should derive Generic
+- [THRIFT-3110](https://issues.apache.org/jira/browse/THRIFT-3110) - Print error log after cross test failures on Travis
+- [THRIFT-3114](https://issues.apache.org/jira/browse/THRIFT-3114) - Using local temp variables to not pollute the global table
+- [THRIFT-3106](https://issues.apache.org/jira/browse/THRIFT-3106) - CMake summary should give more information why a library is set to off
+- [THRIFT-3119](https://issues.apache.org/jira/browse/THRIFT-3119) - Java's TThreadedSelectorServer has indistinguishable log messages in run()
+- [THRIFT-3122](https://issues.apache.org/jira/browse/THRIFT-3122) - Javascript struct constructor should properly initialize struct and container members from plain js arguments
+- [THRIFT-3151](https://issues.apache.org/jira/browse/THRIFT-3151) - Fix links to git-wip* - should be git.apache.org
+- [THRIFT-3167](https://issues.apache.org/jira/browse/THRIFT-3167) - Windows build from source instructions need to be revised
+- [THRIFT-3155](https://issues.apache.org/jira/browse/THRIFT-3155) - move contrib/mingw32-toolchain.cmake to build/cmake/
+- [THRIFT-3160](https://issues.apache.org/jira/browse/THRIFT-3160) - Make generated go enums implement TextMarshaller and TextUnmarshaller interfaces
+- [THRIFT-3150](https://issues.apache.org/jira/browse/THRIFT-3150) - Add an option to thrift go generator to make Read and Write methods private
+- [THRIFT-3149](https://issues.apache.org/jira/browse/THRIFT-3149) - Make ReadFieldN methods in generated Go code private
+- [THRIFT-3172](https://issues.apache.org/jira/browse/THRIFT-3172) - Add tutorial to Thrift web site
+- [THRIFT-3214](https://issues.apache.org/jira/browse/THRIFT-3214) - Add Erlang option for using maps instead of dicts
+- [THRIFT-3201](https://issues.apache.org/jira/browse/THRIFT-3201) - Capture github test artifacts for failed builds
+- [THRIFT-3266](https://issues.apache.org/jira/browse/THRIFT-3266) - c_glib: Multiple compiler warnings building unit tests
+- [THRIFT-3285](https://issues.apache.org/jira/browse/THRIFT-3285) - c_glib: Build library with all warnings enabled, no warnings generated
+- [THRIFT-1954](https://issues.apache.org/jira/browse/THRIFT-1954) - Allow for a separate connection timeout value
+- [THRIFT-2098](https://issues.apache.org/jira/browse/THRIFT-2098) - Add support for Qt5+
+- [THRIFT-2199](https://issues.apache.org/jira/browse/THRIFT-2199) - Remove Dense protocol (was: move to Contrib)
+- [THRIFT-406](https://issues.apache.org/jira/browse/THRIFT-406) - C++ Test suite cleanup
+- [THRIFT-902](https://issues.apache.org/jira/browse/THRIFT-902) - socket and connect timeout in TSocket should be distinguished
+- [THRIFT-388](https://issues.apache.org/jira/browse/THRIFT-388) - Use a separate wire format for async calls
+- [THRIFT-727](https://issues.apache.org/jira/browse/THRIFT-727) - support native C++ language specific exception message
+- [THRIFT-1784](https://issues.apache.org/jira/browse/THRIFT-1784) - pep-3110 compliance for exception handling
+- [THRIFT-1025](https://issues.apache.org/jira/browse/THRIFT-1025) - C++ ServerSocket should inherit from Socket with the necessary Ctor to listen on connections from a specific host
+- [THRIFT-2269](https://issues.apache.org/jira/browse/THRIFT-2269) - Can deploy libthrift-source.jar to maven center repository
+- [THRIFT-2804](https://issues.apache.org/jira/browse/THRIFT-2804) - Pull an interface out of TBaseAsyncProcessor
+- [THRIFT-2806](https://issues.apache.org/jira/browse/THRIFT-2806) - more whitespace fixups
+- [THRIFT-2811](https://issues.apache.org/jira/browse/THRIFT-2811) - Make remote socket address accessible
+- [THRIFT-2809](https://issues.apache.org/jira/browse/THRIFT-2809) - .gitignore update for compiler's visual project
+- [THRIFT-2846](https://issues.apache.org/jira/browse/THRIFT-2846) - Expose ciphers parameter from ssl.wrap_socket()
+- [THRIFT-2859](https://issues.apache.org/jira/browse/THRIFT-2859) - JSON generator: output complete descriptors
+- [THRIFT-2861](https://issues.apache.org/jira/browse/THRIFT-2861) - add buffered transport
+- [THRIFT-2865](https://issues.apache.org/jira/browse/THRIFT-2865) - Test case for Go: SeqId out of sequence
+- [THRIFT-2866](https://issues.apache.org/jira/browse/THRIFT-2866) - Go generator source code is hard to read and maintain
+- [THRIFT-2880](https://issues.apache.org/jira/browse/THRIFT-2880) - Read the network address from the listener if available.
+- [THRIFT-2875](https://issues.apache.org/jira/browse/THRIFT-2875) - Typo in TDenseProtocol.h comment
+- [THRIFT-2874](https://issues.apache.org/jira/browse/THRIFT-2874) - TBinaryProtocol member variable "string_buf_" is never used.
+- [THRIFT-2855](https://issues.apache.org/jira/browse/THRIFT-2855) - Move contributing.md to the root of the repository
+- [THRIFT-2862](https://issues.apache.org/jira/browse/THRIFT-2862) - Enable RTTI and/or build macros for generated code
+- [THRIFT-2876](https://issues.apache.org/jira/browse/THRIFT-2876) - Add test for THRIFT-2526 Assignment operators and copy constructors in c++ don't copy the __isset struct
+- [THRIFT-2897](https://issues.apache.org/jira/browse/THRIFT-2897) - Generate -isEqual: and -hash methods
+- [THRIFT-2909](https://issues.apache.org/jira/browse/THRIFT-2909) - Improve travis build
+- [THRIFT-2921](https://issues.apache.org/jira/browse/THRIFT-2921) - Make Erlang impl ready for OTP 18 release (dict/0 and set/0 are deprecated)
+- [THRIFT-2928](https://issues.apache.org/jira/browse/THRIFT-2928) - Rename the erlang test_server module
+- [THRIFT-2940](https://issues.apache.org/jira/browse/THRIFT-2940) - Allow installing Thrift from git as NPM module by providing package.json in top level directory
+- [THRIFT-2937](https://issues.apache.org/jira/browse/THRIFT-2937) - Allow setting a maximum frame size in TFramedTransport
+- [THRIFT-2976](https://issues.apache.org/jira/browse/THRIFT-2976) - nodejs: xhr and websocket support for browserify
+- [THRIFT-2996](https://issues.apache.org/jira/browse/THRIFT-2996) - Test for Haxe 3.1.3 or better
+- [THRIFT-2969](https://issues.apache.org/jira/browse/THRIFT-2969) - nodejs: DRY up library tests
+- [THRIFT-2973](https://issues.apache.org/jira/browse/THRIFT-2973) - Update Haxe lib readme regarding Haxe 3.1.3
+- [THRIFT-2952](https://issues.apache.org/jira/browse/THRIFT-2952) - Improve handling of Server.Stop()
+- [THRIFT-2964](https://issues.apache.org/jira/browse/THRIFT-2964) - nodejs: move protocols and transports into separate files
+- [THRIFT-2963](https://issues.apache.org/jira/browse/THRIFT-2963) - nodejs - add test coverage
+- [THRIFT-3006](https://issues.apache.org/jira/browse/THRIFT-3006) - Attach 'omitempty' json tag for optional fields in Go
+- [THRIFT-3027](https://issues.apache.org/jira/browse/THRIFT-3027) - Go compiler does not ensure common initialisms have consistent case
+- [THRIFT-3030](https://issues.apache.org/jira/browse/THRIFT-3030) - TThreadedServer: Property for number of clientThreads
+- [THRIFT-3023](https://issues.apache.org/jira/browse/THRIFT-3023) - Go compiler is a little overly conservative with names of attributes
+- [THRIFT-3018](https://issues.apache.org/jira/browse/THRIFT-3018) - Compact protocol for Delphi
+- [THRIFT-3025](https://issues.apache.org/jira/browse/THRIFT-3025) - Change pure Int constants into @enums (where possible)
+- [THRIFT-3031](https://issues.apache.org/jira/browse/THRIFT-3031) - migrate "shouldStop" flag to TServer
+- [THRIFT-3022](https://issues.apache.org/jira/browse/THRIFT-3022) - Compact protocol for Haxe
+- [THRIFT-3041](https://issues.apache.org/jira/browse/THRIFT-3041) - Generate asynchronous clients for Cocoa
+- [THRIFT-3053](https://issues.apache.org/jira/browse/THRIFT-3053) - Perl SSL Socket Support (Encryption)
+- [THRIFT-3247](https://issues.apache.org/jira/browse/THRIFT-3247) - Generate a C++ thread-safe client
+- [THRIFT-3217](https://issues.apache.org/jira/browse/THRIFT-3217) - Provide a little endian variant of the binary protocol in C++
+- [THRIFT-3223](https://issues.apache.org/jira/browse/THRIFT-3223) - TypeScript: Add initial support for Enum Maps
+- [THRIFT-3220](https://issues.apache.org/jira/browse/THRIFT-3220) - Option to suppress @Generated Annotation entirely
+- [THRIFT-3300](https://issues.apache.org/jira/browse/THRIFT-3300) - Reimplement TZlibTransport in Java using streams
+- [THRIFT-3288](https://issues.apache.org/jira/browse/THRIFT-3288) - c_glib: Build unit tests with all warnings enabled, no warnings generated
+- [THRIFT-3347](https://issues.apache.org/jira/browse/THRIFT-3347) - Improve cross test servers and clients
+- [THRIFT-3342](https://issues.apache.org/jira/browse/THRIFT-3342) - Improve ruby cross test client and server compatibility
+- [THRIFT-2296](https://issues.apache.org/jira/browse/THRIFT-2296) - Add C++ Base class for service
+- [THRIFT-3337](https://issues.apache.org/jira/browse/THRIFT-3337) - Add testBool method to cross tests
+- [THRIFT-3303](https://issues.apache.org/jira/browse/THRIFT-3303) - Disable concurrent cabal jobs on Travis to avoid GHC crash
+- [THRIFT-2623](https://issues.apache.org/jira/browse/THRIFT-2623) - Docker container for Thrift
+- [THRIFT-3298](https://issues.apache.org/jira/browse/THRIFT-3298) - thrift endian converters may conflict with other libraries
+- [THRIFT-1559](https://issues.apache.org/jira/browse/THRIFT-1559) - Provide memory pool for TBinaryProtocol to eliminate memory fragmentation
+- [THRIFT-424](https://issues.apache.org/jira/browse/THRIFT-424) - Steal ProtocolBuffers' VarInt implementation for C++
+
+### New Feature
+- [THRIFT-3070](https://issues.apache.org/jira/browse/THRIFT-3070) - Add ability to set the LocalCertificateSelectionCallback
+- [THRIFT-1909](https://issues.apache.org/jira/browse/THRIFT-1909) - Java: Add compiler flag to use the "option pattern" for optional fields
+- [THRIFT-2099](https://issues.apache.org/jira/browse/THRIFT-2099) - Stop TThreadPoolServer with alive connections.
+- [THRIFT-123](https://issues.apache.org/jira/browse/THRIFT-123) - implement TZlibTransport in Java
+- [THRIFT-2368](https://issues.apache.org/jira/browse/THRIFT-2368) - New option: reuse-objects for Java generator
+- [THRIFT-2836](https://issues.apache.org/jira/browse/THRIFT-2836) - Optionally generate C++11 MoveConstructible types
+- [THRIFT-2824](https://issues.apache.org/jira/browse/THRIFT-2824) - Flag to disable html escaping doctext
+- [THRIFT-2819](https://issues.apache.org/jira/browse/THRIFT-2819) - Add WebsSocket client to node.js
+- [THRIFT-3050](https://issues.apache.org/jira/browse/THRIFT-3050) - Client certificate authentication for non-http TLS in C#
+- [THRIFT-3292](https://issues.apache.org/jira/browse/THRIFT-3292) - Implement TZlibTransport in Go
+
+### Question
+- [THRIFT-2583](https://issues.apache.org/jira/browse/THRIFT-2583) - Thrift on xPC target (SpeedGoat)
+- [THRIFT-2592](https://issues.apache.org/jira/browse/THRIFT-2592) - thrift server using c_glib
+- [THRIFT-2832](https://issues.apache.org/jira/browse/THRIFT-2832) - c_glib: Handle string lists correctly
+- [THRIFT-3136](https://issues.apache.org/jira/browse/THRIFT-3136) - thrift installation problem on mac
+- [THRIFT-3346](https://issues.apache.org/jira/browse/THRIFT-3346) - c_glib: Tutorials example crashes saying Calculator.ping implementation returned FALSE but did not set an error
+
+### Sub-task
+- [THRIFT-2578](https://issues.apache.org/jira/browse/THRIFT-2578) - Moving 'make cross' from test.sh to test.py
+- [THRIFT-2734](https://issues.apache.org/jira/browse/THRIFT-2734) - Go coding standards
+- [THRIFT-2748](https://issues.apache.org/jira/browse/THRIFT-2748) - Add Vagrantfile for Centos 6.5
+- [THRIFT-2753](https://issues.apache.org/jira/browse/THRIFT-2753) - Misc. Haxe improvements
+- [THRIFT-2640](https://issues.apache.org/jira/browse/THRIFT-2640) - Compact Protocol in Cocoa
+- [THRIFT-3262](https://issues.apache.org/jira/browse/THRIFT-3262) - warning: overflow in implicit constant conversion in DenseProtoTest.cpp
+- [THRIFT-3194](https://issues.apache.org/jira/browse/THRIFT-3194) - Can't build with go enabled. gomock SCC path incorrect.
+- [THRIFT-3275](https://issues.apache.org/jira/browse/THRIFT-3275) - c_glib tutorial warnings in generated code
+- [THRIFT-1125](https://issues.apache.org/jira/browse/THRIFT-1125) - Multiplexing support for the Ruby Library
+- [THRIFT-2807](https://issues.apache.org/jira/browse/THRIFT-2807) - PHP Code Style
+- [THRIFT-2841](https://issues.apache.org/jira/browse/THRIFT-2841) - Add comprehensive integration tests for the whole Go stack
+- [THRIFT-2815](https://issues.apache.org/jira/browse/THRIFT-2815) - Haxe: Support for Multiplexing Services on any Transport, Protocol and Server
+- [THRIFT-2886](https://issues.apache.org/jira/browse/THRIFT-2886) - Integrate binary type in standard Thrift cross test
+- [THRIFT-2946](https://issues.apache.org/jira/browse/THRIFT-2946) - Enhance usability of cross test framework
+- [THRIFT-2967](https://issues.apache.org/jira/browse/THRIFT-2967) - Add .editorconfig to root
+- [THRIFT-3033](https://issues.apache.org/jira/browse/THRIFT-3033) - Perl: Support for Multiplexing Services on any Transport, Protocol and Server
+- [THRIFT-3174](https://issues.apache.org/jira/browse/THRIFT-3174) - Initialism code in the Go compiler doesn't check first word
+- [THRIFT-3193](https://issues.apache.org/jira/browse/THRIFT-3193) - Option to supress date value in @Generated annotation
+- [THRIFT-3305](https://issues.apache.org/jira/browse/THRIFT-3305) - Missing dist files for 0.9.3 release candidate
+- [THRIFT-3341](https://issues.apache.org/jira/browse/THRIFT-3341) - Add testBool methods
+- [THRIFT-3308](https://issues.apache.org/jira/browse/THRIFT-3308) - Fix broken test cases for 0.9.3 release candidate
+
+### Task
+- [THRIFT-2834](https://issues.apache.org/jira/browse/THRIFT-2834) - Remove semi-colons from python code generator
+- [THRIFT-2853](https://issues.apache.org/jira/browse/THRIFT-2853) - Adjust comments not applying anymore after THRIFT-2852
+
+### Test
+- [THRIFT-3211](https://issues.apache.org/jira/browse/THRIFT-3211) - Add make cross support for php TCompactProtocol
+
+### Wish
+- [THRIFT-2838](https://issues.apache.org/jira/browse/THRIFT-2838) - TNonblockingServer can bind to port 0 (i.e., get an OS-assigned port) but there is no way to get the port number
+
+## 0.9.2
+
+### Bug
+- [THRIFT-2793](https://issues.apache.org/jira/browse/THRIFT-2793) - Go compiler produces uncompilable code
+- [THRIFT-1481](https://issues.apache.org/jira/browse/THRIFT-1481) - Unix domain sockets in C++ do not support the abstract namespace
+- [THRIFT-1455](https://issues.apache.org/jira/browse/THRIFT-1455) - TBinaryProtocolT<Transport_>::writeString casts from size_t to uint32_t, which is not safe on 64-bit platforms
+- [THRIFT-1579](https://issues.apache.org/jira/browse/THRIFT-1579) - PHP Extention - function thrift_protocol_read_binary not working from TBinarySerializer::deserialize
+- [THRIFT-1584](https://issues.apache.org/jira/browse/THRIFT-1584) - Error: could not SetMinThreads in ThreadPool on single-core machines
+- [THRIFT-1614](https://issues.apache.org/jira/browse/THRIFT-1614) - Thrift build from svn repo sources fails with automake-1.12
+- [THRIFT-1047](https://issues.apache.org/jira/browse/THRIFT-1047) - rb_thrift_memory_buffer_write treats arg as string without check, segfaults if you pass non-string
+- [THRIFT-1639](https://issues.apache.org/jira/browse/THRIFT-1639) - Java/Python: Serialization/Deserialization of double type using CompactProtocol
+- [THRIFT-1647](https://issues.apache.org/jira/browse/THRIFT-1647) - NodeJS BufferedTransport does not work beyond the hello-world example
+- [THRIFT-2130](https://issues.apache.org/jira/browse/THRIFT-2130) - Thrift's D library/test: parts of "make check" code do not compile with recent dmd-2.062 through dmd-2.064alpha
+- [THRIFT-2140](https://issues.apache.org/jira/browse/THRIFT-2140) - Error compiling cpp tutorials
+- [THRIFT-2139](https://issues.apache.org/jira/browse/THRIFT-2139) - MSVC 2012 Error - Cannot compile due to BoostThreadFactory
+- [THRIFT-2138](https://issues.apache.org/jira/browse/THRIFT-2138) - pkgconfig file created with wrong include path
+- [THRIFT-2160](https://issues.apache.org/jira/browse/THRIFT-2160) - Warning in thrift.h when compiling with -Wunused and NDEBUG
+- [THRIFT-2158](https://issues.apache.org/jira/browse/THRIFT-2158) - Compact, JSON, and SimpleJSON protocols are not working correctly
+- [THRIFT-2167](https://issues.apache.org/jira/browse/THRIFT-2167) - nodejs lib throws error if options argument isn't passed
+- [THRIFT-2288](https://issues.apache.org/jira/browse/THRIFT-2288) - Go impl of Thrift JSON protocol wrongly writes/expects true/false for bools
+- [THRIFT-2147](https://issues.apache.org/jira/browse/THRIFT-2147) - Thrift IDL grammar allows for dotted identifier names
+- [THRIFT-2145](https://issues.apache.org/jira/browse/THRIFT-2145) - Rack and Thin are not just development dependencies
+- [THRIFT-2267](https://issues.apache.org/jira/browse/THRIFT-2267) - Should be able to choose socket family in Python TSocket
+- [THRIFT-2276](https://issues.apache.org/jira/browse/THRIFT-2276) - java path in spec file needs updating
+- [THRIFT-2281](https://issues.apache.org/jira/browse/THRIFT-2281) - Generated send/recv code ignores errors returned by the underlying protocol
+- [THRIFT-2280](https://issues.apache.org/jira/browse/THRIFT-2280) - TJSONProtocol.Flush() does not really flush the transport
+- [THRIFT-2274](https://issues.apache.org/jira/browse/THRIFT-2274) - TNonblockingServer and TThreadedSelectorServer do not close their channel selectors on exit and leak file descriptors
+- [THRIFT-2265](https://issues.apache.org/jira/browse/THRIFT-2265) - php library doesn't build
+- [THRIFT-2232](https://issues.apache.org/jira/browse/THRIFT-2232) - IsSet* broken in Go
+- [THRIFT-2246](https://issues.apache.org/jira/browse/THRIFT-2246) - Unset enum value is printed by ToString()
+- [THRIFT-2240](https://issues.apache.org/jira/browse/THRIFT-2240) - thrift.vim (contrib) does not correctly handle 'union'
+- [THRIFT-2243](https://issues.apache.org/jira/browse/THRIFT-2243) - TNonblockingServer in thrift crashes when TFramedTransport opens
+- [THRIFT-2230](https://issues.apache.org/jira/browse/THRIFT-2230) - Cannot Build on RHEL/Centos/Amazon Linux 6.x
+- [THRIFT-2247](https://issues.apache.org/jira/browse/THRIFT-2247) - Go generator doesn't deal well with map keys of type binary
+- [THRIFT-2253](https://issues.apache.org/jira/browse/THRIFT-2253) - Python Tornado TTornadoServer base class change
+- [THRIFT-2261](https://issues.apache.org/jira/browse/THRIFT-2261) - java: error: unmappable character for encoding ASCII
+- [THRIFT-2259](https://issues.apache.org/jira/browse/THRIFT-2259) - C#: unexpected null logDelegate() pointer causes AV in TServer.serve()
+- [THRIFT-2225](https://issues.apache.org/jira/browse/THRIFT-2225) - SSLContext destroy before cleanupOpenSSL
+- [THRIFT-2224](https://issues.apache.org/jira/browse/THRIFT-2224) - TSSLSocket.h and TSSLServerSocket.h should use the platfromsocket too
+- [THRIFT-2229](https://issues.apache.org/jira/browse/THRIFT-2229) - thrift failed to build on OSX 10.9 GM
+- [THRIFT-2227](https://issues.apache.org/jira/browse/THRIFT-2227) - Thrift compiler generates spurious warnings with Xlint
+- [THRIFT-2219](https://issues.apache.org/jira/browse/THRIFT-2219) - Thrift gem fails to build on OS X Mavericks with 1.9.3 rubies
+- [THRIFT-2226](https://issues.apache.org/jira/browse/THRIFT-2226) - TServerSocket - keepAlive wrong initialization order
+- [THRIFT-2285](https://issues.apache.org/jira/browse/THRIFT-2285) - TJsonProtocol implementation for Java doesn't allow a slash (/) to be escaped (\/)
+- [THRIFT-2216](https://issues.apache.org/jira/browse/THRIFT-2216) - Extraneous semicolon in TProtocolUtil.h makes clang mad
+- [THRIFT-2215](https://issues.apache.org/jira/browse/THRIFT-2215) - Generated HTML/Graphviz lists referenced enum identifiers as UNKNOWN.
+- [THRIFT-2211](https://issues.apache.org/jira/browse/THRIFT-2211) - Exception constructor does not contain namespace prefix.
+- [THRIFT-2210](https://issues.apache.org/jira/browse/THRIFT-2210) - lib/java TSimpleJSONProtocol can emit invalid JSON
+- [THRIFT-2209](https://issues.apache.org/jira/browse/THRIFT-2209) - Ruby generator -- please namespace classes
+- [THRIFT-2202](https://issues.apache.org/jira/browse/THRIFT-2202) - Delphi TServerImpl.DefaultLogDelegate may stop the server with I/O-Error 105
+- [THRIFT-2201](https://issues.apache.org/jira/browse/THRIFT-2201) - Ternary operator returns different types (build error for some compilers)
+- [THRIFT-2200](https://issues.apache.org/jira/browse/THRIFT-2200) - nested structs cause generate_fingerprint() to slow down at excessive CPU load
+- [THRIFT-2197](https://issues.apache.org/jira/browse/THRIFT-2197) - fix jar output directory in rpm spec file
+- [THRIFT-2196](https://issues.apache.org/jira/browse/THRIFT-2196) - Fix invalid dependency in Makefile.am
+- [THRIFT-2194](https://issues.apache.org/jira/browse/THRIFT-2194) - Node: Not actually prepending residual data in TFramedTransport.receiver
+- [THRIFT-2193](https://issues.apache.org/jira/browse/THRIFT-2193) - Java code generator emits spurious semicolon when deep copying binary data
+- [THRIFT-2191](https://issues.apache.org/jira/browse/THRIFT-2191) - Fix charp JSONProtocol.ReadJSONDouble (specify InvariantCulture)
+- [THRIFT-2214](https://issues.apache.org/jira/browse/THRIFT-2214) - System header sys/param.h is included inside the Thrift namespace
+- [THRIFT-2178](https://issues.apache.org/jira/browse/THRIFT-2178) - Thrift generator returns error exit code on --version
+- [THRIFT-2171](https://issues.apache.org/jira/browse/THRIFT-2171) - NodeJS implementation has extremely low test coverage
+- [THRIFT-2183](https://issues.apache.org/jira/browse/THRIFT-2183) - gem install fails on zsh
+- [THRIFT-2182](https://issues.apache.org/jira/browse/THRIFT-2182) - segfault in regression tests (GC bug in rb_thrift_memory_buffer_write)
+- [THRIFT-2181](https://issues.apache.org/jira/browse/THRIFT-2181) - oneway calls don't work in NodeJS
+- [THRIFT-2169](https://issues.apache.org/jira/browse/THRIFT-2169) - JavaME Thrift Library causes "java.io.IOException: No Response Entries Available" after using the Thrift client for some time
+- [THRIFT-2168](https://issues.apache.org/jira/browse/THRIFT-2168) - Node.js appears broken (at least, examples don't work as intended)
+- [THRIFT-2293](https://issues.apache.org/jira/browse/THRIFT-2293) - TSSLTransportFactory.createSSLContext() leaves files open
+- [THRIFT-2279](https://issues.apache.org/jira/browse/THRIFT-2279) - TSerializer only returns the first 1024 bytes serialized
+- [THRIFT-2278](https://issues.apache.org/jira/browse/THRIFT-2278) - Buffered transport doesn't support writes > buffer size
+- [THRIFT-2275](https://issues.apache.org/jira/browse/THRIFT-2275) - Fix memory leak in golang compact_protocol.
+- [THRIFT-2282](https://issues.apache.org/jira/browse/THRIFT-2282) - Incorect code generated for some typedefs
+- [THRIFT-2009](https://issues.apache.org/jira/browse/THRIFT-2009) - Go redeclaration error
+- [THRIFT-1964](https://issues.apache.org/jira/browse/THRIFT-1964) - 'Isset' causes problems with C#/.NET serializers
+- [THRIFT-2026](https://issues.apache.org/jira/browse/THRIFT-2026) - Fix TCompactProtocol 64 bit builds
+- [THRIFT-2108](https://issues.apache.org/jira/browse/THRIFT-2108) - Fix TAsyncClientManager timeout race
+- [THRIFT-2068](https://issues.apache.org/jira/browse/THRIFT-2068) - Multiple calls from same connection are not processed in node
+- [THRIFT-1750](https://issues.apache.org/jira/browse/THRIFT-1750) - Make compiler build cleanly under visual studio 10
+- [THRIFT-1755](https://issues.apache.org/jira/browse/THRIFT-1755) - Comment parsing bug
+- [THRIFT-1771](https://issues.apache.org/jira/browse/THRIFT-1771) - "make check" fails on x64 for libboost_unit_test_framework.a
+- [THRIFT-1841](https://issues.apache.org/jira/browse/THRIFT-1841) - NodeJS Thrift incorrectly parses non-UTF8-string types
+- [THRIFT-1908](https://issues.apache.org/jira/browse/THRIFT-1908) - Using php thrift_protocol accelerated transfer causes core dump
+- [THRIFT-1892](https://issues.apache.org/jira/browse/THRIFT-1892) - Socket timeouts are declared in milli-seconds, but are actually set in micro-seconds
+- [THRIFT-2303](https://issues.apache.org/jira/browse/THRIFT-2303) - TBufferredTransport not properly closing underlying transport
+- [THRIFT-2313](https://issues.apache.org/jira/browse/THRIFT-2313) - nodejs server crash after processing the first request when using MultiplexedProcessor/FramedBuffer/BinaryProtocol
+- [THRIFT-2311](https://issues.apache.org/jira/browse/THRIFT-2311) - Go: invalid code generated when exception name is a go keyword
+- [THRIFT-2308](https://issues.apache.org/jira/browse/THRIFT-2308) - node: TJSONProtocol parse error when reading from buffered message
+- [THRIFT-2316](https://issues.apache.org/jira/browse/THRIFT-2316) - ccp: TFileTransportTest
+- [THRIFT-2352](https://issues.apache.org/jira/browse/THRIFT-2352) - msvc failed to compile thrift tests
+- [THRIFT-2337](https://issues.apache.org/jira/browse/THRIFT-2337) - Golang does not report TIMED_OUT exceptions
+- [THRIFT-2340](https://issues.apache.org/jira/browse/THRIFT-2340) - Generated server implementation does not send response type EXCEPTION on the Thrift.TApplicationExceptionType.UNKNOWN_METHOD exception
+- [THRIFT-2354](https://issues.apache.org/jira/browse/THRIFT-2354) - Connection errors can lead to case_clause exceptions
+- [THRIFT-2339](https://issues.apache.org/jira/browse/THRIFT-2339) - Uncaught exception in thrift c# driver
+- [THRIFT-2356](https://issues.apache.org/jira/browse/THRIFT-2356) - c++ thrift client not working with ssl (SSL_connect hangs)
+- [THRIFT-2331](https://issues.apache.org/jira/browse/THRIFT-2331) - Missing call to ReadStructBegin() in TApplicationException.Read()
+- [THRIFT-2323](https://issues.apache.org/jira/browse/THRIFT-2323) - Uncompileable Delphi code generated for typedef'd structs
+- [THRIFT-2322](https://issues.apache.org/jira/browse/THRIFT-2322) - Correctly show the number of times ExecutorService (java) has rejected the client.
+- [THRIFT-2389](https://issues.apache.org/jira/browse/THRIFT-2389) - namespaces handled wrongly in acrionscript 3.0 implementation
+- [THRIFT-2388](https://issues.apache.org/jira/browse/THRIFT-2388) - GoLang - Fix data races in simple_server and server_socket
+- [THRIFT-2386](https://issues.apache.org/jira/browse/THRIFT-2386) - Thrift refuses to link yylex
+- [THRIFT-2375](https://issues.apache.org/jira/browse/THRIFT-2375) - Excessive <br>'s in generated HTML
+- [THRIFT-2373](https://issues.apache.org/jira/browse/THRIFT-2373) - warning CS0414 in THttpClient.cs: private field 'Thrift.Transport.THttpClient.connection' assigned but never used
+- [THRIFT-2372](https://issues.apache.org/jira/browse/THRIFT-2372) - thrift/json_protocol.go:160: function ends without a return statement
+- [THRIFT-2371](https://issues.apache.org/jira/browse/THRIFT-2371) - ruby bundler version fails on ~1.3.1, remove and take latest avail
+- [THRIFT-2370](https://issues.apache.org/jira/browse/THRIFT-2370) - Compiler SEGFAULTs generating HTML documentation for complex strucre
+- [THRIFT-2384](https://issues.apache.org/jira/browse/THRIFT-2384) - Binary map keys produce uncompilable code in go
+- [THRIFT-2380](https://issues.apache.org/jira/browse/THRIFT-2380) - unreachable code (CID 1174546, CID 1174679)
+- [THRIFT-2378](https://issues.apache.org/jira/browse/THRIFT-2378) - service method arguments of binary type lead to uncompileable Go code
+- [THRIFT-2363](https://issues.apache.org/jira/browse/THRIFT-2363) - Issue with character encoding of Success returned from Login using Thrift Proxy and NodeJS
+- [THRIFT-2359](https://issues.apache.org/jira/browse/THRIFT-2359) - TBufferedTransport doesn't clear it's buffer on a failed flush call
+- [THRIFT-2428](https://issues.apache.org/jira/browse/THRIFT-2428) - Python 3 setup.py support
+- [THRIFT-2367](https://issues.apache.org/jira/browse/THRIFT-2367) - Build failure: stdlib and boost both define uint64_t
+- [THRIFT-2365](https://issues.apache.org/jira/browse/THRIFT-2365) - C# decodes too many binary bytes from JSON
+- [THRIFT-2402](https://issues.apache.org/jira/browse/THRIFT-2402) - byte count of FrameBuffer in AWAITING_CLOSE state is not subtracted from readBufferBytesAllocated
+- [THRIFT-2396](https://issues.apache.org/jira/browse/THRIFT-2396) - Build Error on MacOSX
+- [THRIFT-2395](https://issues.apache.org/jira/browse/THRIFT-2395) - thrift Ruby gem requires development dependency 'thin' regardless of environment
+- [THRIFT-2414](https://issues.apache.org/jira/browse/THRIFT-2414) - c_glib fix several bug.
+- [THRIFT-2420](https://issues.apache.org/jira/browse/THRIFT-2420) - Go argument parser for methods without arguments does not skip fields
+- [THRIFT-2439](https://issues.apache.org/jira/browse/THRIFT-2439) - Bug in TProtocolDecorator Class causes parsing errors
+- [THRIFT-2419](https://issues.apache.org/jira/browse/THRIFT-2419) - golang - Fix fmt.Errorf in generated code
+- [THRIFT-2418](https://issues.apache.org/jira/browse/THRIFT-2418) - Go handler function panics on internal error
+- [THRIFT-2405](https://issues.apache.org/jira/browse/THRIFT-2405) - Node.js Multiplexer tests fail (silently)
+- [THRIFT-2581](https://issues.apache.org/jira/browse/THRIFT-2581) - TFDTransport destructor should not throw
+- [THRIFT-2575](https://issues.apache.org/jira/browse/THRIFT-2575) - Thrift includes siginfo_t within apache::thrift::protocol namespace
+- [THRIFT-2577](https://issues.apache.org/jira/browse/THRIFT-2577) - TFileTransport missuse of closesocket on windows platform
+- [THRIFT-2576](https://issues.apache.org/jira/browse/THRIFT-2576) - Implement Thrift.Protocol.prototype.skip method in JavaScript library
+- [THRIFT-2588](https://issues.apache.org/jira/browse/THRIFT-2588) - Thrift compiler is not buildable in Visual Studio 2010
+- [THRIFT-2594](https://issues.apache.org/jira/browse/THRIFT-2594) - JS Compiler: Single quotes are not being escaped in constants.
+- [THRIFT-2591](https://issues.apache.org/jira/browse/THRIFT-2591) - TFramedTransport does not handle payloads split across packets correctly
+- [THRIFT-2599](https://issues.apache.org/jira/browse/THRIFT-2599) - Uncompileable Delphi code due to naming conflicts with IDL
+- [THRIFT-2590](https://issues.apache.org/jira/browse/THRIFT-2590) - C++ Visual Studio solution doesn't include Multiplexing support
+- [THRIFT-2595](https://issues.apache.org/jira/browse/THRIFT-2595) - Node.js: Fix global leaks and copy-paste errors
+- [THRIFT-2565](https://issues.apache.org/jira/browse/THRIFT-2565) - autoconf fails to find mingw-g++ cross compiler on travis CI
+- [THRIFT-2555](https://issues.apache.org/jira/browse/THRIFT-2555) - excessive "unused field" comments
+- [THRIFT-2554](https://issues.apache.org/jira/browse/THRIFT-2554) - double initialization in generated Read() method
+- [THRIFT-2551](https://issues.apache.org/jira/browse/THRIFT-2551) - OutOfMemoryError "unable to create new native thread" kills serve thread
+- [THRIFT-2543](https://issues.apache.org/jira/browse/THRIFT-2543) - Generated enum type in haskell should be qualified
+- [THRIFT-2560](https://issues.apache.org/jira/browse/THRIFT-2560) - Thrift compiler generator tries to concat ints with strings using +
+- [THRIFT-2559](https://issues.apache.org/jira/browse/THRIFT-2559) - Centos 6.5 unable to "make" with Thrift 0.9.1
+- [THRIFT-2526](https://issues.apache.org/jira/browse/THRIFT-2526) - Assignment operators and copy constructors in c++ don't copy the __isset struct
+- [THRIFT-2454](https://issues.apache.org/jira/browse/THRIFT-2454) - c_glib: There is no gethostbyname_r() in some OS.
+- [THRIFT-2451](https://issues.apache.org/jira/browse/THRIFT-2451) - Do not use pointers for optional fields with defaults. Do not write such fields if its value set to default. Also, do not use pointers for any optional fields mapped to go map or slice. generate Get accessors
+- [THRIFT-2450](https://issues.apache.org/jira/browse/THRIFT-2450) - include HowToContribute in the src repo
+- [THRIFT-2448](https://issues.apache.org/jira/browse/THRIFT-2448) - thrift/test/test.sh has incorrect Node.js test path
+- [THRIFT-2460](https://issues.apache.org/jira/browse/THRIFT-2460) - unopened socket fd must be less than zero.
+- [THRIFT-2459](https://issues.apache.org/jira/browse/THRIFT-2459) - --version should not exit 1
+- [THRIFT-2468](https://issues.apache.org/jira/browse/THRIFT-2468) - Timestamp handling
+- [THRIFT-2467](https://issues.apache.org/jira/browse/THRIFT-2467) - Unable to build contrib/fb303 on OSX 10.9.2
+- [THRIFT-2466](https://issues.apache.org/jira/browse/THRIFT-2466) - Improper error handling for SSL/TLS connections that don't complete a handshake
+- [THRIFT-2463](https://issues.apache.org/jira/browse/THRIFT-2463) - test/py/RunClientServer.py fails sometimes
+- [THRIFT-2458](https://issues.apache.org/jira/browse/THRIFT-2458) - Generated golang server code for "oneway" methods is incorrect
+- [THRIFT-2456](https://issues.apache.org/jira/browse/THRIFT-2456) - THttpClient fails when using async support outside Silverlight
+- [THRIFT-2524](https://issues.apache.org/jira/browse/THRIFT-2524) - Visual Studio project is missing TThreadedServer files
+- [THRIFT-2523](https://issues.apache.org/jira/browse/THRIFT-2523) - Visual Studio project is missing OverlappedSubmissionThread files
+- [THRIFT-2520](https://issues.apache.org/jira/browse/THRIFT-2520) - cpp:cob_style generates incorrect .tcc file
+- [THRIFT-2508](https://issues.apache.org/jira/browse/THRIFT-2508) - Uncompileable C# code due to language keywords in IDL
+- [THRIFT-2506](https://issues.apache.org/jira/browse/THRIFT-2506) - Update TProtocolException error codes to be used consistently throughout the library
+- [THRIFT-2505](https://issues.apache.org/jira/browse/THRIFT-2505) - go: struct should always be a pointer to avoid copying of potentially size-unbounded structs
+- [THRIFT-2515](https://issues.apache.org/jira/browse/THRIFT-2515) - TLS Method error during make
+- [THRIFT-2503](https://issues.apache.org/jira/browse/THRIFT-2503) - C++: Fix name collision when a struct has a member named "val"
+- [THRIFT-2477](https://issues.apache.org/jira/browse/THRIFT-2477) - thrift --help text with misplaced comma
+- [THRIFT-2492](https://issues.apache.org/jira/browse/THRIFT-2492) - test/cpp does not compile on mac
+- [THRIFT-2500](https://issues.apache.org/jira/browse/THRIFT-2500) - sending random data crashes thrift(golang) service
+- [THRIFT-2475](https://issues.apache.org/jira/browse/THRIFT-2475) - c_glib: buffered_transport_write function return always TRUE.
+- [THRIFT-2495](https://issues.apache.org/jira/browse/THRIFT-2495) - JavaScript/Node string constants lack proper escaping
+- [THRIFT-2491](https://issues.apache.org/jira/browse/THRIFT-2491) - unable to import generated ThriftTest service
+- [THRIFT-2490](https://issues.apache.org/jira/browse/THRIFT-2490) - c_glib: if fail to read a exception from server, client may be occurred double free
+- [THRIFT-2470](https://issues.apache.org/jira/browse/THRIFT-2470) - THttpHandler swallows exceptions from processor
+- [THRIFT-2533](https://issues.apache.org/jira/browse/THRIFT-2533) - Boost version in requirements should be updated
+- [THRIFT-2532](https://issues.apache.org/jira/browse/THRIFT-2532) - Java version in installation requirements should be updated
+- [THRIFT-2529](https://issues.apache.org/jira/browse/THRIFT-2529) - TBufferedTransport split Tcp data bug in nodeJs
+- [THRIFT-2537](https://issues.apache.org/jira/browse/THRIFT-2537) - Path for "go get" does not work (pull request 115)
+- [THRIFT-2443](https://issues.apache.org/jira/browse/THRIFT-2443) - Node fails cross lang tests
+- [THRIFT-2437](https://issues.apache.org/jira/browse/THRIFT-2437) - Author fields in Python setup.py must be strings not lists.
+- [THRIFT-2435](https://issues.apache.org/jira/browse/THRIFT-2435) - Java compiler doesn't like struct member names that are identical to an existing enum or struct type
+- [THRIFT-2434](https://issues.apache.org/jira/browse/THRIFT-2434) - Missing namespace import for php TMultiplexedProcessor implementation
+- [THRIFT-2432](https://issues.apache.org/jira/browse/THRIFT-2432) - Flaky parallel build
+- [THRIFT-2430](https://issues.apache.org/jira/browse/THRIFT-2430) - Crash during TThreadPoolServer shutdown
+- [THRIFT-667](https://issues.apache.org/jira/browse/THRIFT-667) - Period should not be allowed in identifier names
+- [THRIFT-1212](https://issues.apache.org/jira/browse/THRIFT-1212) - Members capital case conflict
+- [THRIFT-2584](https://issues.apache.org/jira/browse/THRIFT-2584) - Error handler not listened on javascript client
+- [THRIFT-2294](https://issues.apache.org/jira/browse/THRIFT-2294) - Incorrect Makefile generation
+- [THRIFT-2601](https://issues.apache.org/jira/browse/THRIFT-2601) - Fix vagrant to work again for builds again
+- [THRIFT-2092](https://issues.apache.org/jira/browse/THRIFT-2092) - TNonblocking server should release handler as soon as connection closes
+- [THRIFT-2557](https://issues.apache.org/jira/browse/THRIFT-2557) - CS0542 member names cannot be the same as their enclosing type
+- [THRIFT-2605](https://issues.apache.org/jira/browse/THRIFT-2605) - TSocket warning on gcc 4.8.3
+- [THRIFT-2607](https://issues.apache.org/jira/browse/THRIFT-2607) - ThreadManager.cpp warning on clang++ 3.4
+- [THRIFT-1998](https://issues.apache.org/jira/browse/THRIFT-1998) - TCompactProtocol.tcc - one more warning on Visual 2010
+- [THRIFT-2610](https://issues.apache.org/jira/browse/THRIFT-2610) - MSVC warning in TSocket.cpp
+- [THRIFT-2614](https://issues.apache.org/jira/browse/THRIFT-2614) - TNonblockingServer.cpp warnings on MSVC
+- [THRIFT-2608](https://issues.apache.org/jira/browse/THRIFT-2608) - TNonblockingServer.cpp warnings on clang 3.4
+- [THRIFT-2606](https://issues.apache.org/jira/browse/THRIFT-2606) - ThreadManager.h warning in clang++ 3.4
+- [THRIFT-2609](https://issues.apache.org/jira/browse/THRIFT-2609) - TFileTransport.h unused field warning (clang 3.4)
+- [THRIFT-2416](https://issues.apache.org/jira/browse/THRIFT-2416) - Cannot use TCompactProtocol with MSVC
+- [THRIFT-1803](https://issues.apache.org/jira/browse/THRIFT-1803) - Ruby Thrift 0.9.0 tries to encode UUID to UTF8 and crashes
+- [THRIFT-2385](https://issues.apache.org/jira/browse/THRIFT-2385) - Problem with gethostbyname2 during make check
+- [THRIFT-2262](https://issues.apache.org/jira/browse/THRIFT-2262) - thrift server 'MutateRow' operation gives no indication of success / failure
+- [THRIFT-2048](https://issues.apache.org/jira/browse/THRIFT-2048) - Prefer boolean context to nullptr_t conversion
+- [THRIFT-2528](https://issues.apache.org/jira/browse/THRIFT-2528) - Thrift Erlang Library: Multiple thrift applications in one bundle
+- [THRIFT-1999](https://issues.apache.org/jira/browse/THRIFT-1999) - warning on gcc 4.7 while compiling BoostMutex.cpp
+- [THRIFT-2104](https://issues.apache.org/jira/browse/THRIFT-2104) - Structs lose binary data when transferred from server to client in Java
+- [THRIFT-2184](https://issues.apache.org/jira/browse/THRIFT-2184) - undefined method rspec_verify for Thrift::MemoryBufferTransport
+- [THRIFT-2351](https://issues.apache.org/jira/browse/THRIFT-2351) - PHP TCompactProtocol has fails to decode messages
+- [THRIFT-2016](https://issues.apache.org/jira/browse/THRIFT-2016) - Resource Leak in thrift struct under compiler/cpp/src/parse/t_function.h
+- [THRIFT-2273](https://issues.apache.org/jira/browse/THRIFT-2273) - Please delete old releases from mirroring system
+- [THRIFT-2270](https://issues.apache.org/jira/browse/THRIFT-2270) - Faulty library version numbering at build or documentation
+- [THRIFT-2203](https://issues.apache.org/jira/browse/THRIFT-2203) - Tests keeping failing on Jenkins and Travis CI
+- [THRIFT-2399](https://issues.apache.org/jira/browse/THRIFT-2399) - thrift.el: recognize "//"-style comments in emacs thrift-mode
+- [THRIFT-2582](https://issues.apache.org/jira/browse/THRIFT-2582) - "FileTransport error" exception is raised when trying to use Java's TFileTransport
+- [THRIFT-1682](https://issues.apache.org/jira/browse/THRIFT-1682) - Multiple thread calling a Service function unsafely causes message corruption and terminates with Broken Pipe
+- [THRIFT-2357](https://issues.apache.org/jira/browse/THRIFT-2357) - recurse option has no effect when generating php
+- [THRIFT-2248](https://issues.apache.org/jira/browse/THRIFT-2248) - Go generator doesn't deal well with map keys of type binary
+- [THRIFT-2426](https://issues.apache.org/jira/browse/THRIFT-2426) - clarify IP rights and contributions from fbthrift
+- [THRIFT-2041](https://issues.apache.org/jira/browse/THRIFT-2041) - TNonblocking server compilation on windows (ARITHMETIC_RIGHT_SHIFT)
+- [THRIFT-2400](https://issues.apache.org/jira/browse/THRIFT-2400) - thrift.el: recognize "//"-style comments in emacs thrift-mode
+- [THRIFT-1717](https://issues.apache.org/jira/browse/THRIFT-1717) - Fix deb build in jenkins
+- [THRIFT-2266](https://issues.apache.org/jira/browse/THRIFT-2266) - ThreadManager.h:24:10: fatal error: 'tr1/functional' file not found on Mac 10.9 (Mavericks)
+- [THRIFT-1300](https://issues.apache.org/jira/browse/THRIFT-1300) - Test failures with parallel builds (make -j)
+- [THRIFT-2487](https://issues.apache.org/jira/browse/THRIFT-2487) - Tutorial requires two IDL files but only one is linked from the Thrift web site
+- [THRIFT-2329](https://issues.apache.org/jira/browse/THRIFT-2329) - missing release tags within git
+- [THRIFT-2306](https://issues.apache.org/jira/browse/THRIFT-2306) - concurent client calls with nodejs
+- [THRIFT-2222](https://issues.apache.org/jira/browse/THRIFT-2222) - ruby gem cannot be compiled on OS X mavericks
+- [THRIFT-2381](https://issues.apache.org/jira/browse/THRIFT-2381) - code which generated by thrift2/hbase.thrift compile error
+- [THRIFT-2390](https://issues.apache.org/jira/browse/THRIFT-2390) - no close event when connection lost
+- [THRIFT-2146](https://issues.apache.org/jira/browse/THRIFT-2146) - Unable to pass multiple "--gen" options to the thrift compiler
+- [THRIFT-2438](https://issues.apache.org/jira/browse/THRIFT-2438) - Unexpected readFieldEnd call causes JSON Parsing errors
+- [THRIFT-2498](https://issues.apache.org/jira/browse/THRIFT-2498) - Error message "Invalid method name" while trying to call HBase Thrift API
+- [THRIFT-841](https://issues.apache.org/jira/browse/THRIFT-841) - Build cruft
+- [THRIFT-2570](https://issues.apache.org/jira/browse/THRIFT-2570) - Wrong URL given in http://thrift.apache.org/developers
+- [THRIFT-2604](https://issues.apache.org/jira/browse/THRIFT-2604) - Fix debian packaging
+- [THRIFT-2618](https://issues.apache.org/jira/browse/THRIFT-2618) - Unignore /aclocal files required for build
+- [THRIFT-2562](https://issues.apache.org/jira/browse/THRIFT-2562) - ./configure create MakeFile in lib/d with errors
+- [THRIFT-2593](https://issues.apache.org/jira/browse/THRIFT-2593) - Unable to build thrift on ubuntu-12.04 (Precise)
+- [THRIFT-2461](https://issues.apache.org/jira/browse/THRIFT-2461) - Can't install thrift-0.8.0 on OS X 10.9.2
+- [THRIFT-2602](https://issues.apache.org/jira/browse/THRIFT-2602) - Fix missing dist files
+- [THRIFT-2620](https://issues.apache.org/jira/browse/THRIFT-2620) - Fix python packaging
+- [THRIFT-2545](https://issues.apache.org/jira/browse/THRIFT-2545) - Test CPP fails to build (possibly typo)
+
+## Documentation
+- [THRIFT-2155](https://issues.apache.org/jira/browse/THRIFT-2155) - Adding one liner guide to rename the version.h.in and rename thrifty.cc.h
+- [THRIFT-1991](https://issues.apache.org/jira/browse/THRIFT-1991) - Add exceptions to examples
+- [THRIFT-2334](https://issues.apache.org/jira/browse/THRIFT-2334) - add a tutorial for node JS
+- [THRIFT-2392](https://issues.apache.org/jira/browse/THRIFT-2392) - Actionscript tutorial
+- [THRIFT-2383](https://issues.apache.org/jira/browse/THRIFT-2383) - contrib: sample for connecting Thrift with Rebus
+- [THRIFT-2382](https://issues.apache.org/jira/browse/THRIFT-2382) - contrib: sample for connecting Thrift with STOMP
+
+### Improvement
+- [THRIFT-1457](https://issues.apache.org/jira/browse/THRIFT-1457) - Capacity of TframedTransport write buffer is never reset
+- [THRIFT-1135](https://issues.apache.org/jira/browse/THRIFT-1135) - Node.js tutorial
+- [THRIFT-1371](https://issues.apache.org/jira/browse/THRIFT-1371) - Socket timeouts (SO_RCVTIMEO and SO_SNDTIMEO) not supported on Solaris
+- [THRIFT-2142](https://issues.apache.org/jira/browse/THRIFT-2142) - Minor tweaks to thrift.el for better emacs package compatibility
+- [THRIFT-2268](https://issues.apache.org/jira/browse/THRIFT-2268) - Modify TSaslTransport to ignore TCP health checks from loadbalancers
+- [THRIFT-2264](https://issues.apache.org/jira/browse/THRIFT-2264) - GitHub page incorrectly states that Thrift is still incubating
+- [THRIFT-2263](https://issues.apache.org/jira/browse/THRIFT-2263) - Always generate good hashCode for Java
+- [THRIFT-2233](https://issues.apache.org/jira/browse/THRIFT-2233) - Java compiler should defensively copy its binary inputs
+- [THRIFT-2239](https://issues.apache.org/jira/browse/THRIFT-2239) - Address FindBugs errors
+- [THRIFT-2249](https://issues.apache.org/jira/browse/THRIFT-2249) - Add SMP Build option to thrift.spec (and three config defines)
+- [THRIFT-2254](https://issues.apache.org/jira/browse/THRIFT-2254) - Exceptions generated by Go compiler should implement error interface
+- [THRIFT-2260](https://issues.apache.org/jira/browse/THRIFT-2260) - Thrift imposes unneeded dependency on commons-lang3
+- [THRIFT-2258](https://issues.apache.org/jira/browse/THRIFT-2258) - Add TLS v1.1/1.2 support to TSSLSocket.cpp
+- [THRIFT-2205](https://issues.apache.org/jira/browse/THRIFT-2205) - Node.js Test Server to support test.js JavaScript Browser test and sundry fixes
+- [THRIFT-2204](https://issues.apache.org/jira/browse/THRIFT-2204) - SSL client for the cocoa client
+- [THRIFT-2172](https://issues.apache.org/jira/browse/THRIFT-2172) - Java compiler allocates optionals array for every struct with an optional field
+- [THRIFT-2185](https://issues.apache.org/jira/browse/THRIFT-2185) - use cabal instead of runhaskell in haskell library
+- [THRIFT-1926](https://issues.apache.org/jira/browse/THRIFT-1926) - PHP Constant Generation Refactoring
+- [THRIFT-2029](https://issues.apache.org/jira/browse/THRIFT-2029) - Port C++ tests to Windows
+- [THRIFT-2054](https://issues.apache.org/jira/browse/THRIFT-2054) - TSimpleFileTransport - Java Lib has no straight forward TTransport based file transport
+- [THRIFT-2040](https://issues.apache.org/jira/browse/THRIFT-2040) - "uninitialized variable" warnings on MSVC/windows
+- [THRIFT-2034](https://issues.apache.org/jira/browse/THRIFT-2034) - Give developers' C++ code direct access to socket FDs on server side
+- [THRIFT-2095](https://issues.apache.org/jira/browse/THRIFT-2095) - Use print function for Python 3 compatiblity
+- [THRIFT-1868](https://issues.apache.org/jira/browse/THRIFT-1868) - Make the TPC backlog configurable in the Java servers
+- [THRIFT-1813](https://issues.apache.org/jira/browse/THRIFT-1813) - Add @Generated annotation to generated classes
+- [THRIFT-1815](https://issues.apache.org/jira/browse/THRIFT-1815) - Code generators line buffer output
+- [THRIFT-2305](https://issues.apache.org/jira/browse/THRIFT-2305) - TFramedTransport empty constructor should probably be private
+- [THRIFT-2304](https://issues.apache.org/jira/browse/THRIFT-2304) - Move client assignments from construtor in method
+- [THRIFT-2309](https://issues.apache.org/jira/browse/THRIFT-2309) - Ruby (gem) & PHP RPM subpackages
+- [THRIFT-2318](https://issues.apache.org/jira/browse/THRIFT-2318) - perl: dependency Class::Accessor not checked
+- [THRIFT-2317](https://issues.apache.org/jira/browse/THRIFT-2317) - exclude tutorial from build
+- [THRIFT-2320](https://issues.apache.org/jira/browse/THRIFT-2320) - Program level doctext does not get attached by parser
+- [THRIFT-2349](https://issues.apache.org/jira/browse/THRIFT-2349) - Golang - improve tutorial
+- [THRIFT-2348](https://issues.apache.org/jira/browse/THRIFT-2348) - PHP Generator: add array typehint to functions
+- [THRIFT-2344](https://issues.apache.org/jira/browse/THRIFT-2344) - configure.ac: compiler-only option
+- [THRIFT-2343](https://issues.apache.org/jira/browse/THRIFT-2343) - Golang - Return a single error for all exceptions instead of multiple return values
+- [THRIFT-2341](https://issues.apache.org/jira/browse/THRIFT-2341) - Enable generation of Delphi XMLDoc comments (a.k.a. "Help Insight")
+- [THRIFT-2355](https://issues.apache.org/jira/browse/THRIFT-2355) - Add SSL and Web Socket Support to Node and JavaScript
+- [THRIFT-2350](https://issues.apache.org/jira/browse/THRIFT-2350) - Add async calls to normal JavaScript
+- [THRIFT-2330](https://issues.apache.org/jira/browse/THRIFT-2330) - Generate PHPDoc comments
+- [THRIFT-2332](https://issues.apache.org/jira/browse/THRIFT-2332) - RPMBUILD: run bootstrap (if needed)
+- [THRIFT-2391](https://issues.apache.org/jira/browse/THRIFT-2391) - simple socket transport for actionscript 3.0
+- [THRIFT-2376](https://issues.apache.org/jira/browse/THRIFT-2376) - nodejs: allow Promise style calls for client and server
+- [THRIFT-2369](https://issues.apache.org/jira/browse/THRIFT-2369) - Add ssl support for nodejs implementation
+- [THRIFT-2401](https://issues.apache.org/jira/browse/THRIFT-2401) - Haskell tutorial compiles
+- [THRIFT-2417](https://issues.apache.org/jira/browse/THRIFT-2417) - C# Union classes are not partial
+- [THRIFT-2415](https://issues.apache.org/jira/browse/THRIFT-2415) - Named pipes server performance & message mode
+- [THRIFT-2404](https://issues.apache.org/jira/browse/THRIFT-2404) - emit warning on (typically inefficient) list<byte>
+- [THRIFT-2398](https://issues.apache.org/jira/browse/THRIFT-2398) - Improve Node Server Library
+- [THRIFT-2397](https://issues.apache.org/jira/browse/THRIFT-2397) - Add CORS and CSP support for JavaScript and Node.js libraries
+- [THRIFT-2407](https://issues.apache.org/jira/browse/THRIFT-2407) - use markdown (rename README => README.md)
+- [THRIFT-2300](https://issues.apache.org/jira/browse/THRIFT-2300) - D configure info output should follow same format as other languages
+- [THRIFT-2579](https://issues.apache.org/jira/browse/THRIFT-2579) - Windows CE support
+- [THRIFT-2574](https://issues.apache.org/jira/browse/THRIFT-2574) - Compiler option to generate namespace directories for Ruby
+- [THRIFT-2571](https://issues.apache.org/jira/browse/THRIFT-2571) - Simplify cross compilation using CMake
+- [THRIFT-2569](https://issues.apache.org/jira/browse/THRIFT-2569) - Introduce file to specify third party library locations on Windows
+- [THRIFT-2568](https://issues.apache.org/jira/browse/THRIFT-2568) - Implement own certificate handler
+- [THRIFT-2552](https://issues.apache.org/jira/browse/THRIFT-2552) - eliminate warning from configure.ac
+- [THRIFT-2549](https://issues.apache.org/jira/browse/THRIFT-2549) - Generate json tag for struct members. use go.tag annotation to override the default generated tag.
+- [THRIFT-2544](https://issues.apache.org/jira/browse/THRIFT-2544) - Add support for socket transport for c# library when using Windows Phone projects
+- [THRIFT-2453](https://issues.apache.org/jira/browse/THRIFT-2453) - haskell tutorial: fix up division by 0 example
+- [THRIFT-2449](https://issues.apache.org/jira/browse/THRIFT-2449) - Enhance typedef structure to distinguish between forwards and real typedefs
+- [THRIFT-2446](https://issues.apache.org/jira/browse/THRIFT-2446) - There is no way to handle server stream errors
+- [THRIFT-2455](https://issues.apache.org/jira/browse/THRIFT-2455) - Allow client certificates to be used with THttpClient
+- [THRIFT-2511](https://issues.apache.org/jira/browse/THRIFT-2511) - Node.js needs the compact protocol
+- [THRIFT-2493](https://issues.apache.org/jira/browse/THRIFT-2493) - Node.js lib needs HTTP client
+- [THRIFT-2502](https://issues.apache.org/jira/browse/THRIFT-2502) - Optimize go implementations of binary and compact protocols for speed
+- [THRIFT-2494](https://issues.apache.org/jira/browse/THRIFT-2494) - Add enum toString helper function in c_glib
+- [THRIFT-2471](https://issues.apache.org/jira/browse/THRIFT-2471) - Make cpp.ref annotation language agnostic
+- [THRIFT-2497](https://issues.apache.org/jira/browse/THRIFT-2497) - server and client for test/go, also several fixes and improvements
+- [THRIFT-2535](https://issues.apache.org/jira/browse/THRIFT-2535) - TJSONProtocol when serialized yields TField ids rather than names
+- [THRIFT-2220](https://issues.apache.org/jira/browse/THRIFT-2220) - Add a new struct structv?
+- [THRIFT-1352](https://issues.apache.org/jira/browse/THRIFT-1352) - Thrift server
+- [THRIFT-989](https://issues.apache.org/jira/browse/THRIFT-989) - Push boost m4 macros upstream
+- [THRIFT-1349](https://issues.apache.org/jira/browse/THRIFT-1349) - Remove unnecessary print outs
+- [THRIFT-2496](https://issues.apache.org/jira/browse/THRIFT-2496) - server and client for test/go, also several fixes and improvements
+- [THRIFT-1114](https://issues.apache.org/jira/browse/THRIFT-1114) - Maven publish shouldn't require passwords hardcoded in settings.xml
+- [THRIFT-2043](https://issues.apache.org/jira/browse/THRIFT-2043) - visual 2010 warnings - unreachable code
+- [THRIFT-1683](https://issues.apache.org/jira/browse/THRIFT-1683) - Implement alternatives to Javascript Client side Transport protocol, just as NPAPI and WebSocket.
+- [THRIFT-1746](https://issues.apache.org/jira/browse/THRIFT-1746) - provide a SPDX file
+- [THRIFT-1772](https://issues.apache.org/jira/browse/THRIFT-1772) - Serialization does not check types of embedded structures.
+- [THRIFT-2387](https://issues.apache.org/jira/browse/THRIFT-2387) - nodejs: external imports should be centralized in index.js
+- [THRIFT-2037](https://issues.apache.org/jira/browse/THRIFT-2037) - More general macro THRIFT_UNUSED_VARIABLE
+
+### New Feature
+- [THRIFT-1012](https://issues.apache.org/jira/browse/THRIFT-1012) - Transport for DataInput DataOutput interface
+- [THRIFT-2256](https://issues.apache.org/jira/browse/THRIFT-2256) - Using c++11/c++0x std library replace boost library
+- [THRIFT-2250](https://issues.apache.org/jira/browse/THRIFT-2250) - JSON and MemoryBuffer for JavaME
+- [THRIFT-2114](https://issues.apache.org/jira/browse/THRIFT-2114) - Python Service Remote SSL Option
+- [THRIFT-1719](https://issues.apache.org/jira/browse/THRIFT-1719) - SASL client support for Python
+- [THRIFT-1894](https://issues.apache.org/jira/browse/THRIFT-1894) - Thrift multi-threaded async Java Server using Java 7 AsynchronousChannelGroup
+- [THRIFT-1893](https://issues.apache.org/jira/browse/THRIFT-1893) - HTTP/JSON server/client for node js
+- [THRIFT-2347](https://issues.apache.org/jira/browse/THRIFT-2347) - C# TLS Transport based on THRIFT-181
+- [THRIFT-2377](https://issues.apache.org/jira/browse/THRIFT-2377) - Allow addition of custom HTTP Headers to an HTTP Transport
+- [THRIFT-2408](https://issues.apache.org/jira/browse/THRIFT-2408) - Named Pipe Transport Option for C#
+- [THRIFT-2572](https://issues.apache.org/jira/browse/THRIFT-2572) - Add string/collection length limit checks (from C++) to java protocol readers
+- [THRIFT-2469](https://issues.apache.org/jira/browse/THRIFT-2469) - "java:fullcamel" option to automatically camel-case underscored attribute names
+- [THRIFT-795](https://issues.apache.org/jira/browse/THRIFT-795) - Importing service functions (simulation multiple inheritance)
+- [THRIFT-2164](https://issues.apache.org/jira/browse/THRIFT-2164) - Add a Get/Post Http Server to Node along with examples
+- [THRIFT-2255](https://issues.apache.org/jira/browse/THRIFT-2255) - add Parent Class for generated Struct class
+
+### Question
+- [THRIFT-2539](https://issues.apache.org/jira/browse/THRIFT-2539) - Tsocket.cpp addrinfo ai_flags = AI_ADDRCONFIG
+- [THRIFT-2440](https://issues.apache.org/jira/browse/THRIFT-2440) - how to connect as3 to java by thrift ,
+- [THRIFT-2379](https://issues.apache.org/jira/browse/THRIFT-2379) - Memmory leaking while using multithreading in C++ server.
+- [THRIFT-2277](https://issues.apache.org/jira/browse/THRIFT-2277) - Thrift: installing fb303 error
+- [THRIFT-2567](https://issues.apache.org/jira/browse/THRIFT-2567) - Csharp slow ?
+- [THRIFT-2573](https://issues.apache.org/jira/browse/THRIFT-2573) - thrift 0.9.2 release
+
+### Sub-task
+- [THRIFT-981](https://issues.apache.org/jira/browse/THRIFT-981) - cocoa: add version Info to the library
+- [THRIFT-2132](https://issues.apache.org/jira/browse/THRIFT-2132) - Go: Support for Multiplexing Services on any Transport, Protocol and Server
+- [THRIFT-2299](https://issues.apache.org/jira/browse/THRIFT-2299) - TJsonProtocol implementation for Ruby does not allow for both possible slash (solidus) encodings
+- [THRIFT-2298](https://issues.apache.org/jira/browse/THRIFT-2298) - TJsonProtocol implementation for C# does not allow for both possible slash (solidus) encodings
+- [THRIFT-2297](https://issues.apache.org/jira/browse/THRIFT-2297) - TJsonProtocol implementation for Delphi does not allow for both possible slash (solidus) encodings
+- [THRIFT-2271](https://issues.apache.org/jira/browse/THRIFT-2271) - JavaScript: Support for Multiplexing Services
+- [THRIFT-2251](https://issues.apache.org/jira/browse/THRIFT-2251) - go test for compact protocol is not running
+- [THRIFT-2195](https://issues.apache.org/jira/browse/THRIFT-2195) - Delphi: Add event handlers for server and processing events
+- [THRIFT-2176](https://issues.apache.org/jira/browse/THRIFT-2176) - TSimpleJSONProtocol.ReadFieldBegin() does not return field type and ID
+- [THRIFT-2175](https://issues.apache.org/jira/browse/THRIFT-2175) - Wrong field type set for binary
+- [THRIFT-2174](https://issues.apache.org/jira/browse/THRIFT-2174) - Deserializing JSON fails in specific cases
+- [THRIFT-2053](https://issues.apache.org/jira/browse/THRIFT-2053) - NodeJS: Support for Multiplexing Services
+- [THRIFT-1914](https://issues.apache.org/jira/browse/THRIFT-1914) - Python: Support for Multiplexing Services on any Transport, Protocol and Server
+- [THRIFT-1810](https://issues.apache.org/jira/browse/THRIFT-1810) - add ruby to test/test.sh
+- [THRIFT-2310](https://issues.apache.org/jira/browse/THRIFT-2310) - PHP: Client-side support for Multiplexing Services
+- [THRIFT-2346](https://issues.apache.org/jira/browse/THRIFT-2346) - C#: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
+- [THRIFT-2345](https://issues.apache.org/jira/browse/THRIFT-2345) - Delphi: UTF-8 sent by PHP as JSON is not understood by TJsonProtocol
+- [THRIFT-2338](https://issues.apache.org/jira/browse/THRIFT-2338) - First doctext wrongly interpreted as program doctext in some cases
+- [THRIFT-2325](https://issues.apache.org/jira/browse/THRIFT-2325) - SSL test certificates
+- [THRIFT-2358](https://issues.apache.org/jira/browse/THRIFT-2358) - C++: add compact protocol to cross language test suite
+- [THRIFT-2425](https://issues.apache.org/jira/browse/THRIFT-2425) - PHP: Server-side support for Multiplexing Services
+- [THRIFT-2421](https://issues.apache.org/jira/browse/THRIFT-2421) - Tree/Recursive struct support in thrift
+- [THRIFT-2290](https://issues.apache.org/jira/browse/THRIFT-2290) - Update Go tutorial to align with THRIFT-2232
+- [THRIFT-2558](https://issues.apache.org/jira/browse/THRIFT-2558) - CSharp compiler generator tries to concat ints with strings using +
+- [THRIFT-2507](https://issues.apache.org/jira/browse/THRIFT-2507) - Additional LUA TProtocolException error code needed?
+- [THRIFT-2499](https://issues.apache.org/jira/browse/THRIFT-2499) - Compiler: allow annotations without "= value"
+- [THRIFT-2534](https://issues.apache.org/jira/browse/THRIFT-2534) - Cross language test results should recorded to a status.md or status.html file automatically
+- [THRIFT-66](https://issues.apache.org/jira/browse/THRIFT-66) - Java: Allow multiplexing multiple services over a single TCP connection
+- [THRIFT-1681](https://issues.apache.org/jira/browse/THRIFT-1681) - Add Lua Support
+- [THRIFT-1727](https://issues.apache.org/jira/browse/THRIFT-1727) - Ruby-1.9: data loss: "binary" fields are re-encoded
+- [THRIFT-1726](https://issues.apache.org/jira/browse/THRIFT-1726) - Ruby-1.9: "binary" fields are represented by string whose encoding is "UTF-8"
+- [THRIFT-988](https://issues.apache.org/jira/browse/THRIFT-988) - perl: add version Info to the library via configure
+- [THRIFT-334](https://issues.apache.org/jira/browse/THRIFT-334) - Compact Protocol for PHP
+- [THRIFT-2444](https://issues.apache.org/jira/browse/THRIFT-2444) - pull request 88: thrift: clean up enum value assignment
+
+### Task
+- [THRIFT-2223](https://issues.apache.org/jira/browse/THRIFT-2223) - Spam links on wiki
+- [THRIFT-2566](https://issues.apache.org/jira/browse/THRIFT-2566) - Please create a DOAP file for your TLP
+- [THRIFT-2237](https://issues.apache.org/jira/browse/THRIFT-2237) - Update archive to contain all versions
+- [THRIFT-962](https://issues.apache.org/jira/browse/THRIFT-962) - Tutorial page on our website is really unhelpful
+
+### Test
+- [THRIFT-2327](https://issues.apache.org/jira/browse/THRIFT-2327) - nodejs: nodejs test suite should be bundled with the library
+- [THRIFT-2445](https://issues.apache.org/jira/browse/THRIFT-2445) - THRIFT-2384 (code generation for go maps with binary keys) should be tested
+- [THRIFT-2501](https://issues.apache.org/jira/browse/THRIFT-2501) - C# The test parameters from the TestServer and TestClient are different from the http://thrift.apache.org/test/
+
+### Wish
+- [THRIFT-2190](https://issues.apache.org/jira/browse/THRIFT-2190) - Add the JavaScript thrift.js lib to the Bower registry
+- [THRIFT-2076](https://issues.apache.org/jira/browse/THRIFT-2076) - boost::optional instead of __isset
+
+## 0.9.1
+
+### Bug
+- [THRIFT-1440](https://issues.apache.org/jira/browse/THRIFT-1440) - debian packaging: minor-ish policy problems
+- [THRIFT-1402](https://issues.apache.org/jira/browse/THRIFT-1402) - Generated Y_types.js does not require() X_types.js when an include in the IDL file was used
+- [THRIFT-1551](https://issues.apache.org/jira/browse/THRIFT-1551) - 2 thrift file define only struct (no service), one include another, the gen nodejs file didn't have "requires" at the top
+- [THRIFT-1264](https://issues.apache.org/jira/browse/THRIFT-1264) - TSocketClient is queried by run loop after deallocation in Cocoa
+- [THRIFT-1600](https://issues.apache.org/jira/browse/THRIFT-1600) - Thrift Go Compiler and Library out of date with Go 1 Release.
+- [THRIFT-1603](https://issues.apache.org/jira/browse/THRIFT-1603) - Thrift IDL allows for multiple exceptions, args or struct member names to be the same
+- [THRIFT-1062](https://issues.apache.org/jira/browse/THRIFT-1062) - Problems with python tutorials
+- [THRIFT-864](https://issues.apache.org/jira/browse/THRIFT-864) - default value fails if identifier is a struct
+- [THRIFT-930](https://issues.apache.org/jira/browse/THRIFT-930) - Ruby and Haskell bindings don't properly support DESTDIR (makes packaging painful)
+- [THRIFT-820](https://issues.apache.org/jira/browse/THRIFT-820) - The readLength attribute of TBinaryProtocol is used as an instance variable and is decremented on each call of checkReadLength
+- [THRIFT-1640](https://issues.apache.org/jira/browse/THRIFT-1640) - None of the tutorials linked on the website contain content
+- [THRIFT-1637](https://issues.apache.org/jira/browse/THRIFT-1637) - NPM registry does not include version 0.8
+- [THRIFT-1648](https://issues.apache.org/jira/browse/THRIFT-1648) - NodeJS clients always receive 0 for 'double' values.
+- [THRIFT-1660](https://issues.apache.org/jira/browse/THRIFT-1660) - Python Thrift library can be installed with pip but not easy_install
+- [THRIFT-1657](https://issues.apache.org/jira/browse/THRIFT-1657) - Chrome browser sending OPTIONS method before POST in xmlHttpRequest
+- [THRIFT-2118](https://issues.apache.org/jira/browse/THRIFT-2118) - Certificate error handling still incorrect
+- [THRIFT-2137](https://issues.apache.org/jira/browse/THRIFT-2137) - Ruby test lib fails jenkins build #864
+- [THRIFT-2136](https://issues.apache.org/jira/browse/THRIFT-2136) - Vagrant build not compiling java, ruby, php, go libs due to missing dependencies
+- [THRIFT-2135](https://issues.apache.org/jira/browse/THRIFT-2135) - GO lib leaves behind test files that are auto generated
+- [THRIFT-2134](https://issues.apache.org/jira/browse/THRIFT-2134) - mingw-cross-compile script failing with strip errors
+- [THRIFT-2133](https://issues.apache.org/jira/browse/THRIFT-2133) - java TestTBinaryProtocol.java test failing
+- [THRIFT-2126](https://issues.apache.org/jira/browse/THRIFT-2126) - lib/cpp/src/thrift/concurrency/STD* files missing from DIST
+- [THRIFT-2125](https://issues.apache.org/jira/browse/THRIFT-2125) - debian missing from DIST
+- [THRIFT-2124](https://issues.apache.org/jira/browse/THRIFT-2124) - .o, .so, .la, .deps, .libs, gen-* files left tutorials, test and lib/cpp when making DIST
+- [THRIFT-2123](https://issues.apache.org/jira/browse/THRIFT-2123) - GO lib missing files in DIST build
+- [THRIFT-2121](https://issues.apache.org/jira/browse/THRIFT-2121) - Compilation bug for Node.js
+- [THRIFT-2129](https://issues.apache.org/jira/browse/THRIFT-2129) - php ext missing from dist
+- [THRIFT-2128](https://issues.apache.org/jira/browse/THRIFT-2128) - lib GO tests fail with funct ends without a return statement
+- [THRIFT-2286](https://issues.apache.org/jira/browse/THRIFT-2286) - Failed to compile Thrift0.9.1 with boost1.55 by VS2010 if select Debug-mt&x64 mode.
+- [THRIFT-1973](https://issues.apache.org/jira/browse/THRIFT-1973) - TCompactProtocol in C# lib does not serialize and deserialize negative int32 and int64 number correctly
+- [THRIFT-1992](https://issues.apache.org/jira/browse/THRIFT-1992) - casts in TCompactProtocol.tcc causing "dereferencing type-punned pointer will break strict-aliasing rules" warnings from gcc
+- [THRIFT-1930](https://issues.apache.org/jira/browse/THRIFT-1930) - C# generates unsigned byte for Thrift "byte" type
+- [THRIFT-1929](https://issues.apache.org/jira/browse/THRIFT-1929) - Update website to use Mirrors for downloads
+- [THRIFT-1928](https://issues.apache.org/jira/browse/THRIFT-1928) - Race may still exist in TFileTransport::flush()
+- [THRIFT-1934](https://issues.apache.org/jira/browse/THRIFT-1934) - Tabs in Example section on main page are not working
+- [THRIFT-1933](https://issues.apache.org/jira/browse/THRIFT-1933) - Delphi generator crashes when a typedef references another typedef from an included file
+- [THRIFT-1942](https://issues.apache.org/jira/browse/THRIFT-1942) - Binary accelerated cpp extension does not use Thrift namespaces for Exceptions
+- [THRIFT-1959](https://issues.apache.org/jira/browse/THRIFT-1959) - C#: Add Union TMemoryBuffer support
+- [THRIFT-1958](https://issues.apache.org/jira/browse/THRIFT-1958) - C#: Use static Object.Equals instead of .Equals() calls in equals
+- [THRIFT-1957](https://issues.apache.org/jira/browse/THRIFT-1957) - NodeJS TFramedTransport and TBufferedTransport read bytes as unsigned
+- [THRIFT-1955](https://issues.apache.org/jira/browse/THRIFT-1955) - Union Type writer generated in C# does not WriteStructBegin
+- [THRIFT-1952](https://issues.apache.org/jira/browse/THRIFT-1952) - Travis CI
+- [THRIFT-1949](https://issues.apache.org/jira/browse/THRIFT-1949) - WP7 build broken
+- [THRIFT-1943](https://issues.apache.org/jira/browse/THRIFT-1943) - docstrings for enum values are ignored
+- [THRIFT-2070](https://issues.apache.org/jira/browse/THRIFT-2070) - Improper `HexChar' and 'HexVal' implementation in TJSONProtocol.cs
+- [THRIFT-2017](https://issues.apache.org/jira/browse/THRIFT-2017) - Resource Leak in thrift struct under compiler/cpp/src/parse/t_program.h
+- [THRIFT-2032](https://issues.apache.org/jira/browse/THRIFT-2032) - C# client leaks sockets/handles
+- [THRIFT-1996](https://issues.apache.org/jira/browse/THRIFT-1996) - JavaME Constants generation is broken / inconsistent with regular Java generation
+- [THRIFT-2002](https://issues.apache.org/jira/browse/THRIFT-2002) - Haskell: Test use Data.Maybe instead of Maybe
+- [THRIFT-2051](https://issues.apache.org/jira/browse/THRIFT-2051) - Vagrant fails to build erlang
+- [THRIFT-2050](https://issues.apache.org/jira/browse/THRIFT-2050) - Vagrant C# lib compile fails with TException missing
+- [THRIFT-1978](https://issues.apache.org/jira/browse/THRIFT-1978) - Ruby: Thrift should allow for the SSL verify mode to be set
+- [THRIFT-1984](https://issues.apache.org/jira/browse/THRIFT-1984) - namespace collision in python bindings
+- [THRIFT-1988](https://issues.apache.org/jira/browse/THRIFT-1988) - When trying to build a debian package it fails as the file NEWS doesn't exist
+- [THRIFT-1975](https://issues.apache.org/jira/browse/THRIFT-1975) - TBinaryProtocol CheckLength can't be used for a client
+- [THRIFT-1995](https://issues.apache.org/jira/browse/THRIFT-1995) - '.' allowed at end of identifier generates non-compilable code
+- [THRIFT-2112](https://issues.apache.org/jira/browse/THRIFT-2112) - Error in Go generator when using typedefs in map keys
+- [THRIFT-2088](https://issues.apache.org/jira/browse/THRIFT-2088) - Typos in Thrift compiler help text
+- [THRIFT-2080](https://issues.apache.org/jira/browse/THRIFT-2080) - C# multiplex processor does not catch IOException
+- [THRIFT-2082](https://issues.apache.org/jira/browse/THRIFT-2082) - Executing "gmake clean" is broken
+- [THRIFT-2102](https://issues.apache.org/jira/browse/THRIFT-2102) - constants are not referencing to correct type when included from another thrift file
+- [THRIFT-2100](https://issues.apache.org/jira/browse/THRIFT-2100) - typedefs are not correctly referenced when including from other thrift files
+- [THRIFT-2066](https://issues.apache.org/jira/browse/THRIFT-2066) - 'make install' does not install two headers required for C++ bindings
+- [THRIFT-2065](https://issues.apache.org/jira/browse/THRIFT-2065) - Not valid constants filename in Java
+- [THRIFT-2047](https://issues.apache.org/jira/browse/THRIFT-2047) - Thrift.Protocol.TCompactProtocol, intToZigZag data lost (TCompactProtocol.cs)
+- [THRIFT-2036](https://issues.apache.org/jira/browse/THRIFT-2036) - Thrift gem warns about class variable access from top level
+- [THRIFT-2057](https://issues.apache.org/jira/browse/THRIFT-2057) - Vagrant fails on php tests
+- [THRIFT-2105](https://issues.apache.org/jira/browse/THRIFT-2105) - Generated code for default values of collections ignores t_field::T_REQUIRED
+- [THRIFT-2091](https://issues.apache.org/jira/browse/THRIFT-2091) - Unnecessary 'friend' declaration causes warning in TWinsockSingleton
+- [THRIFT-2090](https://issues.apache.org/jira/browse/THRIFT-2090) - Go generator, fix including of other thrift files
+- [THRIFT-2106](https://issues.apache.org/jira/browse/THRIFT-2106) - Fix support for namespaces in GO generator
+- [THRIFT-1783](https://issues.apache.org/jira/browse/THRIFT-1783) - C# doesn't handle required fields correctly
+- [THRIFT-1782](https://issues.apache.org/jira/browse/THRIFT-1782) - async only defined in silverlight
+- [THRIFT-1779](https://issues.apache.org/jira/browse/THRIFT-1779) - Missing process_XXXX method in generated TProcessor implementation for all 'oneway' service functions
+- [THRIFT-1692](https://issues.apache.org/jira/browse/THRIFT-1692) - SO_REUSEADDR allows for socket hijacking on Windows
+- [THRIFT-1720](https://issues.apache.org/jira/browse/THRIFT-1720) - JRuby times out on successful connection
+- [THRIFT-1713](https://issues.apache.org/jira/browse/THRIFT-1713) - Named and Anonymous Pipe transport (Delphi)
+- [THRIFT-1699](https://issues.apache.org/jira/browse/THRIFT-1699) - Native Union#read has extra read_field_end call
+- [THRIFT-1749](https://issues.apache.org/jira/browse/THRIFT-1749) - Python TSSLSocket error handling obscures actual error
+- [THRIFT-1748](https://issues.apache.org/jira/browse/THRIFT-1748) - Guard and RWGuard macros defined in global namespace
+- [THRIFT-1734](https://issues.apache.org/jira/browse/THRIFT-1734) - Front webpage is still advertising v0.8 as current release
+- [THRIFT-1729](https://issues.apache.org/jira/browse/THRIFT-1729) - C glib refactor left empty folders in svn
+- [THRIFT-1767](https://issues.apache.org/jira/browse/THRIFT-1767) - unions can't have required fields (Delphi)
+- [THRIFT-1765](https://issues.apache.org/jira/browse/THRIFT-1765) - Incorrect error message printed for null or negative keys
+- [THRIFT-1778](https://issues.apache.org/jira/browse/THRIFT-1778) - Configure requires manual intervention due to tar failure
+- [THRIFT-1777](https://issues.apache.org/jira/browse/THRIFT-1777) - TPipeServer is UNSTOPPABLE
+- [THRIFT-1753](https://issues.apache.org/jira/browse/THRIFT-1753) - Multiple C++ Windows, OSX, and iOS portability issues
+- [THRIFT-1756](https://issues.apache.org/jira/browse/THRIFT-1756) - 'make -j 8' fails with "unterminated #ifdef" error
+- [THRIFT-1773](https://issues.apache.org/jira/browse/THRIFT-1773) - Python library should run on python 2.4
+- [THRIFT-1769](https://issues.apache.org/jira/browse/THRIFT-1769) - unions can't have required fields (C++)
+- [THRIFT-1768](https://issues.apache.org/jira/browse/THRIFT-1768) - unions can't have required fields (Compiler)
+- [THRIFT-1666](https://issues.apache.org/jira/browse/THRIFT-1666) - htonll usage in TBinaryProtocol.tcc generates warning with MSVC2010
+- [THRIFT-1919](https://issues.apache.org/jira/browse/THRIFT-1919) - libthrift depends on httpcore-4.1.3 (directly) and httpcore-4.1.4 (transitively)
+- [THRIFT-1864](https://issues.apache.org/jira/browse/THRIFT-1864) - implement event handler for non-blocking server
+- [THRIFT-1859](https://issues.apache.org/jira/browse/THRIFT-1859) - Generated error c++ code with -out and include_prefix param
+- [THRIFT-1869](https://issues.apache.org/jira/browse/THRIFT-1869) - TThreadPoolServer (java) dies when threadpool is consumed
+- [THRIFT-1842](https://issues.apache.org/jira/browse/THRIFT-1842) - Memory leak with Pipes
+- [THRIFT-1838](https://issues.apache.org/jira/browse/THRIFT-1838) - Can't build compiler on OS X because of missing thrifty.h
+- [THRIFT-1846](https://issues.apache.org/jira/browse/THRIFT-1846) - Restore socket.h header to support builds with Android NDK
+- [THRIFT-1850](https://issues.apache.org/jira/browse/THRIFT-1850) - make check hangs on TSocket tests in TransportTest.cpp
+- [THRIFT-1873](https://issues.apache.org/jira/browse/THRIFT-1873) - Binary protocol factory ignores struct read/write flags
+- [THRIFT-1872](https://issues.apache.org/jira/browse/THRIFT-1872) - issues with TBufferedTransport buffer
+- [THRIFT-1904](https://issues.apache.org/jira/browse/THRIFT-1904) - Incorrect code is generated for typedefs which use included types
+- [THRIFT-1903](https://issues.apache.org/jira/browse/THRIFT-1903) - PHP namespaces cause binary protocols to not be used
+- [THRIFT-1895](https://issues.apache.org/jira/browse/THRIFT-1895) - Delphi: reserved variable name "result" not detected properly
+- [THRIFT-1881](https://issues.apache.org/jira/browse/THRIFT-1881) - TNonblockingServer does not release open connections or threads on shutdown
+- [THRIFT-1888](https://issues.apache.org/jira/browse/THRIFT-1888) - Java Thrift client can't connect to Python Thrift server on same host
+- [THRIFT-1831](https://issues.apache.org/jira/browse/THRIFT-1831) - Bug in list deserializer
+- [THRIFT-1824](https://issues.apache.org/jira/browse/THRIFT-1824) - many compile warning, becase Thread.h includes config.h
+- [THRIFT-1823](https://issues.apache.org/jira/browse/THRIFT-1823) - Missing parenthesis breaks "IS_..." macro in generated code
+- [THRIFT-1806](https://issues.apache.org/jira/browse/THRIFT-1806) - Python generation always truncates __init__.py files
+- [THRIFT-1795](https://issues.apache.org/jira/browse/THRIFT-1795) - Race condition in TThreadedServerPool java implementation
+- [THRIFT-1794](https://issues.apache.org/jira/browse/THRIFT-1794) - C# asyncctp broken
+- [THRIFT-1804](https://issues.apache.org/jira/browse/THRIFT-1804) - Binary+compact protocol single byte error in Ruby library (ARM architecture): caused by different char signedness
+- [THRIFT-1800](https://issues.apache.org/jira/browse/THRIFT-1800) - Documentation text not always escaped correctly when rendered to HTML
+- [THRIFT-1788](https://issues.apache.org/jira/browse/THRIFT-1788) - C#: Constants static constructor does not compile
+- [THRIFT-1816](https://issues.apache.org/jira/browse/THRIFT-1816) - Need "require" included thrift files in "xxx_types.js"
+- [THRIFT-1907](https://issues.apache.org/jira/browse/THRIFT-1907) - Compiling namespace and sub-namespace directives for unrecognized generators should only be a warning
+- [THRIFT-1913](https://issues.apache.org/jira/browse/THRIFT-1913) - skipping unknown fields in java unions
+- [THRIFT-2553](https://issues.apache.org/jira/browse/THRIFT-2553) - C++ linker error - transport/TSocket
+- [THRIFT-274](https://issues.apache.org/jira/browse/THRIFT-274) - Towards a working release/versioning process
+
+### Documentation
+- [THRIFT-1971](https://issues.apache.org/jira/browse/THRIFT-1971) - [Graphviz] Adds tutorial/general description documentation
+- [THRIFT-2001](https://issues.apache.org/jira/browse/THRIFT-2001) - http://thrift.apache.org/ Example "C++ Server" tab is broken
+
+### Improvement
+- [THRIFT-1574](https://issues.apache.org/jira/browse/THRIFT-1574) - Apache project branding requirements: DOAP file [PATCH]
+- [THRIFT-1347](https://issues.apache.org/jira/browse/THRIFT-1347) - Unify the exceptions returned in generated Go code
+- [THRIFT-1353](https://issues.apache.org/jira/browse/THRIFT-1353) - Switch to performance branch, get rid of BinaryParser
+- [THRIFT-1629](https://issues.apache.org/jira/browse/THRIFT-1629) - Ruby 1.9 Compatibility during Thrift configure, make, install
+- [THRIFT-991](https://issues.apache.org/jira/browse/THRIFT-991) - Refactor Haskell code and generator
+- [THRIFT-990](https://issues.apache.org/jira/browse/THRIFT-990) - Sanify gettimeofday usage codebase-wide
+- [THRIFT-791](https://issues.apache.org/jira/browse/THRIFT-791) - Let C++ TSimpleServer be driven by an external main loop
+- [THRIFT-2117](https://issues.apache.org/jira/browse/THRIFT-2117) - Cocoa TBinaryProtocol strictWrite should be set to true by default
+- [THRIFT-2014](https://issues.apache.org/jira/browse/THRIFT-2014) - Change C++ lib includes to use <namespace/> style throughout
+- [THRIFT-1972](https://issues.apache.org/jira/browse/THRIFT-1972) - Add support for async processors
+- [THRIFT-1970](https://issues.apache.org/jira/browse/THRIFT-1970) - [Graphviz] Adds option to render exceptions relationships
+- [THRIFT-1966](https://issues.apache.org/jira/browse/THRIFT-1966) - Support different files for SSL certificates and keys
+- [THRIFT-1965](https://issues.apache.org/jira/browse/THRIFT-1965) - Adds Graphviz (graph description language) generator
+- [THRIFT-1956](https://issues.apache.org/jira/browse/THRIFT-1956) - Switch to Apache Commons Lang 3
+- [THRIFT-1962](https://issues.apache.org/jira/browse/THRIFT-1962) - Multiplex processor should send any TApplicationException back to client
+- [THRIFT-1960](https://issues.apache.org/jira/browse/THRIFT-1960) - main() declares 22 unused gen bools
+- [THRIFT-1951](https://issues.apache.org/jira/browse/THRIFT-1951) - libthrift.jar has source files in it
+- [THRIFT-1997](https://issues.apache.org/jira/browse/THRIFT-1997) - Add accept backlog configuration method to TServerSocket
+- [THRIFT-2003](https://issues.apache.org/jira/browse/THRIFT-2003) - Deprecate senum
+- [THRIFT-2052](https://issues.apache.org/jira/browse/THRIFT-2052) - Vagrant machine image defaults to only 384MB of RAM
+- [THRIFT-1980](https://issues.apache.org/jira/browse/THRIFT-1980) - Modernize Go tooling, fix go client libary.
+- [THRIFT-1977](https://issues.apache.org/jira/browse/THRIFT-1977) - C# compiler should generate constant files prefixed with thrift file name
+- [THRIFT-1985](https://issues.apache.org/jira/browse/THRIFT-1985) - add a Vagrantfile to build and test Apache Thrift fully reproducable
+- [THRIFT-1994](https://issues.apache.org/jira/browse/THRIFT-1994) - Deprecate slist
+- [THRIFT-1993](https://issues.apache.org/jira/browse/THRIFT-1993) - Factory to create instances from known (generated) interface types with Delphi
+- [THRIFT-2081](https://issues.apache.org/jira/browse/THRIFT-2081) - Specified timeout should be used in TSocket.Open()
+- [THRIFT-2084](https://issues.apache.org/jira/browse/THRIFT-2084) - Delphi: Ability to create entity Thrift-generated instances based on TypeInfo
+- [THRIFT-2083](https://issues.apache.org/jira/browse/THRIFT-2083) - Improve the go lib: buffered Transport, save memory allocation, handle concurrent request
+- [THRIFT-2109](https://issues.apache.org/jira/browse/THRIFT-2109) - Secure connections should be supported in Go
+- [THRIFT-2107](https://issues.apache.org/jira/browse/THRIFT-2107) - minor Go generator fixes
+- [THRIFT-1695](https://issues.apache.org/jira/browse/THRIFT-1695) - allow warning-free compilation in VS 2012 and GNU 4.6
+- [THRIFT-1735](https://issues.apache.org/jira/browse/THRIFT-1735) - integrate tutorial into regular build
+- [THRIFT-1716](https://issues.apache.org/jira/browse/THRIFT-1716) - max allowed connections should be PIPE_UNLIMITED_INSTANCES
+- [THRIFT-1715](https://issues.apache.org/jira/browse/THRIFT-1715) - Allow excluding python parts when building contrib/fb303
+- [THRIFT-1733](https://issues.apache.org/jira/browse/THRIFT-1733) - Fix RPM build issues on RHEL6/OL6 systems
+- [THRIFT-1728](https://issues.apache.org/jira/browse/THRIFT-1728) - Upgradation of httpcomponents
+- [THRIFT-1876](https://issues.apache.org/jira/browse/THRIFT-1876) - Use enum names instead of casted integers in assignments
+- [THRIFT-1874](https://issues.apache.org/jira/browse/THRIFT-1874) - timeout for the server-side end of a named pipe
+- [THRIFT-1897](https://issues.apache.org/jira/browse/THRIFT-1897) - Support validation of required fields
+- [THRIFT-1896](https://issues.apache.org/jira/browse/THRIFT-1896) - Add TBase protocol for Cocoa
+- [THRIFT-1880](https://issues.apache.org/jira/browse/THRIFT-1880) - Make named pipes server work asynchronously (overlapped) to allow for clean server stops
+- [THRIFT-1878](https://issues.apache.org/jira/browse/THRIFT-1878) - Add the possibility to send custom headers
+- [THRIFT-1882](https://issues.apache.org/jira/browse/THRIFT-1882) - Use single include
+- [THRIFT-1793](https://issues.apache.org/jira/browse/THRIFT-1793) - C#: Use static read instead of instance read
+- [THRIFT-1799](https://issues.apache.org/jira/browse/THRIFT-1799) - Option to generate HTML in "standalone mode"
+- [THRIFT-1815](https://issues.apache.org/jira/browse/THRIFT-1815) - Code generators line buffer output
+- [THRIFT-1890](https://issues.apache.org/jira/browse/THRIFT-1890) - C++: Make named pipes server work asynchronously
+- [THRIFT-474](https://issues.apache.org/jira/browse/THRIFT-474) - Generating Ruby on Rails friendly code
+
+### New Feature
+- [THRIFT-801](https://issues.apache.org/jira/browse/THRIFT-801) - Provide an interactive shell (irb) when generating ruby bindings
+- [THRIFT-2292](https://issues.apache.org/jira/browse/THRIFT-2292) - Android Library Project
+- [THRIFT-2012](https://issues.apache.org/jira/browse/THRIFT-2012) - Modernizing Go
+- [THRIFT-1969](https://issues.apache.org/jira/browse/THRIFT-1969) - C#: Tests not properly linked from the solution
+- [THRIFT-1785](https://issues.apache.org/jira/browse/THRIFT-1785) - C#: Add TMemoryBuffer serializer/deserializer
+- [THRIFT-1780](https://issues.apache.org/jira/browse/THRIFT-1780) - Add option to generate nullable values
+- [THRIFT-1786](https://issues.apache.org/jira/browse/THRIFT-1786) - C# Union Typing
+- [THRIFT-591](https://issues.apache.org/jira/browse/THRIFT-591) - Make the C++ runtime library be compatible with Windows and Visual Studio
+- [THRIFT-514](https://issues.apache.org/jira/browse/THRIFT-514) - Add option to configure compiler output directory
+
+### Question
+- [THRIFT-1764](https://issues.apache.org/jira/browse/THRIFT-1764) - how to get the context of client when on a rpc call in server side?
+- [THRIFT-1791](https://issues.apache.org/jira/browse/THRIFT-1791) - thrift's namespace directive when generating haskell code
+
+### Sub-task
+- [THRIFT-1594](https://issues.apache.org/jira/browse/THRIFT-1594) - Java test clients should have a return codes that reflect whether it succeeds or not.
+- [THRIFT-1595](https://issues.apache.org/jira/browse/THRIFT-1595) - Java test server should follow the documented behavior as of THRIFT-1590
+- [THRIFT-986](https://issues.apache.org/jira/browse/THRIFT-986) - st: add version Info to the library
+- [THRIFT-985](https://issues.apache.org/jira/browse/THRIFT-985) - php: add version Info to the library
+- [THRIFT-984](https://issues.apache.org/jira/browse/THRIFT-984) - ocaml: add version Info to the library
+- [THRIFT-1924](https://issues.apache.org/jira/browse/THRIFT-1924) - Delphi: Inconsistency in serialization of optional fields
+- [THRIFT-1922](https://issues.apache.org/jira/browse/THRIFT-1922) - C#: Inconsistency in serialization of optional fields
+- [THRIFT-1961](https://issues.apache.org/jira/browse/THRIFT-1961) - C# tests should be in lib/csharp/test/...
+- [THRIFT-1822](https://issues.apache.org/jira/browse/THRIFT-1822) - PHP unit test does not work
+- [THRIFT-1902](https://issues.apache.org/jira/browse/THRIFT-1902) - C++: Support for Multiplexing Services on any Transport, Protocol and Server
+- [THRIFT-1901](https://issues.apache.org/jira/browse/THRIFT-1901) - C#: Support for Multiplexing Services on any Transport, Protocol and Server
+- [THRIFT-1899](https://issues.apache.org/jira/browse/THRIFT-1899) - Delphi: Support for Multiplexing Services on any Transport, Protocol and Server
+- [THRIFT-563](https://issues.apache.org/jira/browse/THRIFT-563) - Support for Multiplexing Services on any Transport, Protocol and Server
+
+## 0.9
+
+### Bug
+- [THRIFT-1438](https://issues.apache.org/jira/browse/THRIFT-1438) - lib/cpp/src/windows/config.h should read version from configure.ac rather than a #define
+- [THRIFT-1446](https://issues.apache.org/jira/browse/THRIFT-1446) - Compile error with Delphi 2009 in constant initializer
+- [THRIFT-1450](https://issues.apache.org/jira/browse/THRIFT-1450) - Problems building thrift 0.8.0 for Python and Ruby
+- [THRIFT-1449](https://issues.apache.org/jira/browse/THRIFT-1449) - Ruby client does not work on solaris (?)
+- [THRIFT-1447](https://issues.apache.org/jira/browse/THRIFT-1447) - NullpointerException in ProcessFunction.class :in "oneway" method
+- [THRIFT-1433](https://issues.apache.org/jira/browse/THRIFT-1433) - TServerSocket fix for MSVC
+- [THRIFT-1429](https://issues.apache.org/jira/browse/THRIFT-1429) - The nonblocking servers is supposed to use TransportFactory to read the data
+- [THRIFT-1427](https://issues.apache.org/jira/browse/THRIFT-1427) - PHP library uses non-multibyte safe functions with mbstring function overloading
+- [THRIFT-1421](https://issues.apache.org/jira/browse/THRIFT-1421) - Debian Packages can not be built
+- [THRIFT-1394](https://issues.apache.org/jira/browse/THRIFT-1394) - Treatment of optional fields is not consistent between C++ and Java
+- [THRIFT-1511](https://issues.apache.org/jira/browse/THRIFT-1511) - Server with oneway support ( JAVA )
+- [THRIFT-1496](https://issues.apache.org/jira/browse/THRIFT-1496) - PHP compiler not namespacing enums
+- [THRIFT-1495](https://issues.apache.org/jira/browse/THRIFT-1495) - PHP TestClient fatals on missing class
+- [THRIFT-1508](https://issues.apache.org/jira/browse/THRIFT-1508) - TServerSocket does not allow for the user to specify the IP address to bind to
+- [THRIFT-1504](https://issues.apache.org/jira/browse/THRIFT-1504) - Cocoa Generator should use local file imports for base Thrift headers
+- [THRIFT-1512](https://issues.apache.org/jira/browse/THRIFT-1512) - Thrift socket support for Windows XP
+- [THRIFT-1502](https://issues.apache.org/jira/browse/THRIFT-1502) - TSimpleServer::serve(): Do not print out error message if server was stopped.
+- [THRIFT-1501](https://issues.apache.org/jira/browse/THRIFT-1501) - PHP old namespaces not generated for enums
+- [THRIFT-1483](https://issues.apache.org/jira/browse/THRIFT-1483) - java compiler does not generate type parameters for services in extended clauses
+- [THRIFT-1479](https://issues.apache.org/jira/browse/THRIFT-1479) - Compiled PHP process functions missing writeMessageEnd()
+- [THRIFT-1492](https://issues.apache.org/jira/browse/THRIFT-1492) - enabling c_glib render thrift unusable (even for C++ code)
+- [THRIFT-1491](https://issues.apache.org/jira/browse/THRIFT-1491) - Uninitialize processorFactory_ member in TServer.h
+- [THRIFT-1475](https://issues.apache.org/jira/browse/THRIFT-1475) - Incomplete records generation for Erlang
+- [THRIFT-1486](https://issues.apache.org/jira/browse/THRIFT-1486) - Javascript manual testserver not returning content types
+- [THRIFT-1488](https://issues.apache.org/jira/browse/THRIFT-1488) - src/concurrency/Thread.h:91:58: error: invalid conversion from 'pthread_t {aka _opaque_pthread_t*}' to 'apache::thrift::concurrency::Thread::id_t {aka long long unsigned int}' [-fpermissive]
+- [THRIFT-1490](https://issues.apache.org/jira/browse/THRIFT-1490) - Windows-specific header files - fixes & tweaks
+- [THRIFT-1526](https://issues.apache.org/jira/browse/THRIFT-1526) - Union TupleSchemeFactory returns StandardSchemes
+- [THRIFT-1527](https://issues.apache.org/jira/browse/THRIFT-1527) - Generated implementation of tupleReadStruct in unions return null when the setfield is unrecognized
+- [THRIFT-1524](https://issues.apache.org/jira/browse/THRIFT-1524) - TNonBlockingServer does not compile in Visual Studio 2010
+- [THRIFT-1529](https://issues.apache.org/jira/browse/THRIFT-1529) - TupleProtocol can unintentionally include an extra byte in bit vectors when number of optional fields is an integral of 8
+- [THRIFT-1473](https://issues.apache.org/jira/browse/THRIFT-1473) - JSON context stack may be left in an incorrect state when an exception is thrown during read or write operations
+- [THRIFT-1456](https://issues.apache.org/jira/browse/THRIFT-1456) - System.Net.HttpWebRequest' does not contain a definition for 'Proxy'
+- [THRIFT-1468](https://issues.apache.org/jira/browse/THRIFT-1468) - Memory leak in TSaslServerTransport
+- [THRIFT-1461](https://issues.apache.org/jira/browse/THRIFT-1461) - Recent TNonblockingServer changes broke --enable-boostthreads=yes, Windows
+- [THRIFT-1460](https://issues.apache.org/jira/browse/THRIFT-1460) - why not add unicode strings support to python directly?
+- [THRIFT-1464](https://issues.apache.org/jira/browse/THRIFT-1464) - AbstractNonblockingServer.FrameBuffer TNonblockingTransport accessor changed from public to private
+- [THRIFT-1467](https://issues.apache.org/jira/browse/THRIFT-1467) - Possible AV with empty strings when using JSON protocol
+- [THRIFT-1523](https://issues.apache.org/jira/browse/THRIFT-1523) - clientTimeout not worked as expected in TServerSocket created by TSSLTransportFactory
+- [THRIFT-1537](https://issues.apache.org/jira/browse/THRIFT-1537) - TFramedTransport issues
+- [THRIFT-1519](https://issues.apache.org/jira/browse/THRIFT-1519) - Thirft Build Failure referencing rb_intern2 symbol
+- [THRIFT-1518](https://issues.apache.org/jira/browse/THRIFT-1518) - Generated C++ code only sends the first optional field in the write() function for a struct.
+- [THRIFT-1515](https://issues.apache.org/jira/browse/THRIFT-1515) - NameError: global name 'TApplicationException' is not defined
+- [THRIFT-1554](https://issues.apache.org/jira/browse/THRIFT-1554) - Inherited service methods are not resolved in derived service implementations
+- [THRIFT-1553](https://issues.apache.org/jira/browse/THRIFT-1553) - thrift nodejs service side can't read map structure, key as enum, value as Object
+- [THRIFT-1575](https://issues.apache.org/jira/browse/THRIFT-1575) - Typo in server/TThreadPoolServer.h
+- [THRIFT-1327](https://issues.apache.org/jira/browse/THRIFT-1327) - Fix Spec Suite under Ruby-1.8.7 (works for MRI Ruby-1.9.2)
+- [THRIFT-1326](https://issues.apache.org/jira/browse/THRIFT-1326) - on some platforms, #include <stdint.h> is necessary to be included in Thrift.h
+- [THRIFT-1159](https://issues.apache.org/jira/browse/THRIFT-1159) - THttpClient->Flush() issue (connection thru proxy)
+- [THRIFT-1277](https://issues.apache.org/jira/browse/THRIFT-1277) - Node.js serializes false booleans as null
+- [THRIFT-1224](https://issues.apache.org/jira/browse/THRIFT-1224) - Cannot insert UTF-8 text
+- [THRIFT-1267](https://issues.apache.org/jira/browse/THRIFT-1267) - Node.js can't throw exceptions.
+- [THRIFT-1338](https://issues.apache.org/jira/browse/THRIFT-1338) - Do not use an unpatched autoconf 2.65 to generate release tarball
+- [THRIFT-1128](https://issues.apache.org/jira/browse/THRIFT-1128) - MAC OS X: thrift.h incompatibility with Thrift.h
+- [THRIFT-1631](https://issues.apache.org/jira/browse/THRIFT-1631) - Fix C++ server constructor typos
+- [THRIFT-1602](https://issues.apache.org/jira/browse/THRIFT-1602) - PHP C Extension is not Compatible with PHP 5.4
+- [THRIFT-1610](https://issues.apache.org/jira/browse/THRIFT-1610) - IWebProxy not available on WP7 platform
+- [THRIFT-1606](https://issues.apache.org/jira/browse/THRIFT-1606) - Race condition in BoostThreadFactory.cpp
+- [THRIFT-1604](https://issues.apache.org/jira/browse/THRIFT-1604) - Python exception handeling for changes from PEP 3110
+- [THRIFT-1607](https://issues.apache.org/jira/browse/THRIFT-1607) - Incorrect file modes for several source files
+- [THRIFT-1583](https://issues.apache.org/jira/browse/THRIFT-1583) - c_glib leaks memory
+- [THRIFT-1582](https://issues.apache.org/jira/browse/THRIFT-1582) - Bad includes of nested thrift files in c_glib
+- [THRIFT-1578](https://issues.apache.org/jira/browse/THRIFT-1578) - C_GLib generated code does not compile
+- [THRIFT-1597](https://issues.apache.org/jira/browse/THRIFT-1597) - TJSONProtocol.php is missing from Makefile.am
+- [THRIFT-1591](https://issues.apache.org/jira/browse/THRIFT-1591) - Enable TCP_NODELAY for ruby gem
+- [THRIFT-1624](https://issues.apache.org/jira/browse/THRIFT-1624) - Isset Generated differently on different platforms
+- [THRIFT-1622](https://issues.apache.org/jira/browse/THRIFT-1622) - Incorrect size returned on read
+- [THRIFT-1621](https://issues.apache.org/jira/browse/THRIFT-1621) - Memory leaks
+- [THRIFT-1612](https://issues.apache.org/jira/browse/THRIFT-1612) - Base64 encoding is broken
+- [THRIFT-1627](https://issues.apache.org/jira/browse/THRIFT-1627) - compiler built using compilers.vcxproj cannot be used to build some test .thrift files
+- [THRIFT-1571](https://issues.apache.org/jira/browse/THRIFT-1571) - Update Ruby HTTP transport for recent Ruby versions
+- [THRIFT-1023](https://issues.apache.org/jira/browse/THRIFT-1023) - Thrift encoding (UTF-8) issue with Ruby 1.9.2
+- [THRIFT-1090](https://issues.apache.org/jira/browse/THRIFT-1090) - Document the generation of a file called "Constants.java"
+- [THRIFT-1082](https://issues.apache.org/jira/browse/THRIFT-1082) - Thrift::FramedTransport sometimes calls close() on an undefined value
+- [THRIFT-956](https://issues.apache.org/jira/browse/THRIFT-956) - Python module's version meta-data should be updated
+- [THRIFT-973](https://issues.apache.org/jira/browse/THRIFT-973) - Cocoa library won't compile using clang
+- [THRIFT-1632](https://issues.apache.org/jira/browse/THRIFT-1632) - ruby: data corruption in thrift_native implementation of MemoryBufferTransport
+- [THRIFT-1665](https://issues.apache.org/jira/browse/THRIFT-1665) - TBinaryProtocol: exceeded message length raises generic TException
+- [THRIFT-1664](https://issues.apache.org/jira/browse/THRIFT-1664) - Reference to non-existing variable in build script
+- [THRIFT-1663](https://issues.apache.org/jira/browse/THRIFT-1663) - Java Thrift server is not throwing exceptions
+- [THRIFT-1662](https://issues.apache.org/jira/browse/THRIFT-1662) - "removeObject:" should be "removeObserver:" in [-TSocketServer dealloc]?
+- [THRIFT-1643](https://issues.apache.org/jira/browse/THRIFT-1643) - Denial of Service attack in TBinaryProtocol.readString
+- [THRIFT-1674](https://issues.apache.org/jira/browse/THRIFT-1674) - Update Thrift D library to be compatible with 2.060
+- [THRIFT-1673](https://issues.apache.org/jira/browse/THRIFT-1673) - Ruby compile flags for extension for multi arch builds (os x)
+- [THRIFT-1655](https://issues.apache.org/jira/browse/THRIFT-1655) - Configure still trying to use thrift_generators in output
+- [THRIFT-1654](https://issues.apache.org/jira/browse/THRIFT-1654) - c_glib thrift_socket_read() returns corrupted data
+- [THRIFT-1653](https://issues.apache.org/jira/browse/THRIFT-1653) - TThreadedSelectorServer leaks CLOSE_WAIT sockets
+- [THRIFT-1658](https://issues.apache.org/jira/browse/THRIFT-1658) - Java thrift server is not throwing TApplicationException
+- [THRIFT-1656](https://issues.apache.org/jira/browse/THRIFT-1656) - Setting proper headers in THttpServer.cpp so that "Cross-Origin Resource Sharing" on js client can work.
+- [THRIFT-1652](https://issues.apache.org/jira/browse/THRIFT-1652) - TSaslTransport does not log the error when kerberos auth fails
+- [THRIFT-2272](https://issues.apache.org/jira/browse/THRIFT-2272) - CLONE - Denial of Service attack in TBinaryProtocol.readString
+- [THRIFT-2086](https://issues.apache.org/jira/browse/THRIFT-2086) - Invalid generated code for Node.JS when using namespaces
+- [THRIFT-1686](https://issues.apache.org/jira/browse/THRIFT-1686) - t_php_generator.cc uses "and" instead of "&&", and causes compiler errors with Visual Studio
+- [THRIFT-1693](https://issues.apache.org/jira/browse/THRIFT-1693) - libthrift has dependency on two different versions of httpcore
+- [THRIFT-1689](https://issues.apache.org/jira/browse/THRIFT-1689) - don't exit(-1) in TNonblockingServer
+- [THRIFT-1679](https://issues.apache.org/jira/browse/THRIFT-1679) - NodeJS: protocol readString() should treat string as utf8, not binary
+- [THRIFT-1721](https://issues.apache.org/jira/browse/THRIFT-1721) - Dist broken due to 0.8.0 to 0.9.0 changes
+- [THRIFT-1710](https://issues.apache.org/jira/browse/THRIFT-1710) - Minor issues in test case code
+- [THRIFT-1709](https://issues.apache.org/jira/browse/THRIFT-1709) - Warning "Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first" in TBinaryProtocol.cs at ReadInt64()
+- [THRIFT-1707](https://issues.apache.org/jira/browse/THRIFT-1707) - [ruby] Adjust server_spec.rb for RSpec 2.11.x and Ruby 1.9.3
+- [THRIFT-1671](https://issues.apache.org/jira/browse/THRIFT-1671) - Cocoa code generator does not put keywords into generated method calls
+- [THRIFT-1670](https://issues.apache.org/jira/browse/THRIFT-1670) - Incompatibilities between different versions of a Thrift interface
+- [THRIFT-1669](https://issues.apache.org/jira/browse/THRIFT-1669) - NameError: global name 'TApplicationException' is not defined
+- [THRIFT-1668](https://issues.apache.org/jira/browse/THRIFT-1668) - Compile error in contrib/fb303, thrift/TDispatchProcessor.h: No such file or directory
+- [THRIFT-1845](https://issues.apache.org/jira/browse/THRIFT-1845) - Fix compiler warning caused by implicit string conversion with Xcode 4.6
+- [THRIFT-304](https://issues.apache.org/jira/browse/THRIFT-304) - Building the Python library requires development headers
+- [THRIFT-369](https://issues.apache.org/jira/browse/THRIFT-369) - sets and maps break equality
+- [THRIFT-556](https://issues.apache.org/jira/browse/THRIFT-556) - Ruby compiler does not correctly referred to top-level modules when a submodule masks the top-level name
+- [THRIFT-481](https://issues.apache.org/jira/browse/THRIFT-481) - indentation of ruby classes is off by a few
+
+### Improvement
+- [THRIFT-1498](https://issues.apache.org/jira/browse/THRIFT-1498) - Allow TThreadedPoolServer.Args to pass a ExecutorService
+- [THRIFT-1444](https://issues.apache.org/jira/browse/THRIFT-1444) - FunctionRunner - add syntactic sugar to create shared_ptrs
+- [THRIFT-1443](https://issues.apache.org/jira/browse/THRIFT-1443) - define a TProcessor helper class to implement process()
+- [THRIFT-1441](https://issues.apache.org/jira/browse/THRIFT-1441) - Generate constructor with parameters for exception class to let it update message property automatically.
+- [THRIFT-1520](https://issues.apache.org/jira/browse/THRIFT-1520) - Embed version number in erlang .app file
+- [THRIFT-1480](https://issues.apache.org/jira/browse/THRIFT-1480) - python: remove tabs, adjust whitespace and address PEP8 warnings
+- [THRIFT-1485](https://issues.apache.org/jira/browse/THRIFT-1485) - Performance: pass large and/or refcounted arguments as "const"
+- [THRIFT-1484](https://issues.apache.org/jira/browse/THRIFT-1484) - Introduce phpunit test suite
+- [THRIFT-1532](https://issues.apache.org/jira/browse/THRIFT-1532) - The type specifications in the generated Erlang code should include "undefined" where it's used as a default value
+- [THRIFT-1534](https://issues.apache.org/jira/browse/THRIFT-1534) - Required fields in the Delphi code generator.
+- [THRIFT-1469](https://issues.apache.org/jira/browse/THRIFT-1469) - Java isset space optimization
+- [THRIFT-1465](https://issues.apache.org/jira/browse/THRIFT-1465) - Visibility of methods in generated java code
+- [THRIFT-1453](https://issues.apache.org/jira/browse/THRIFT-1453) - Don't change types of arguments when serializing with thrift php extension
+- [THRIFT-1452](https://issues.apache.org/jira/browse/THRIFT-1452) - generate a swap() method for all generated structs
+- [THRIFT-1451](https://issues.apache.org/jira/browse/THRIFT-1451) - FramedTransport: Prevent infinite loop when writing
+- [THRIFT-1521](https://issues.apache.org/jira/browse/THRIFT-1521) - Two patches for more Performance
+- [THRIFT-1555](https://issues.apache.org/jira/browse/THRIFT-1555) - Delphi version of the tutorial code
+- [THRIFT-1535](https://issues.apache.org/jira/browse/THRIFT-1535) - Why thrift don't use wrapped class for optional fields ?
+- [THRIFT-1204](https://issues.apache.org/jira/browse/THRIFT-1204) - Ruby autogenerated files should require 'thrift' gem
+- [THRIFT-1344](https://issues.apache.org/jira/browse/THRIFT-1344) - Using the httpc module directly rather than the deprecated http layer
+- [THRIFT-1343](https://issues.apache.org/jira/browse/THRIFT-1343) - no_auto_import min/2 to avoid compile warning
+- [THRIFT-1340](https://issues.apache.org/jira/browse/THRIFT-1340) - Add support of ARC to Objective-C
+- [THRIFT-1611](https://issues.apache.org/jira/browse/THRIFT-1611) - Improved code generation for typedefs
+- [THRIFT-1593](https://issues.apache.org/jira/browse/THRIFT-1593) - Pass on errors like "connection closed" to the handler module
+- [THRIFT-1615](https://issues.apache.org/jira/browse/THRIFT-1615) - PHP Namespace
+- [THRIFT-1567](https://issues.apache.org/jira/browse/THRIFT-1567) - Thrift/cpp: Allow alternate classes to be used for
+- [THRIFT-1072](https://issues.apache.org/jira/browse/THRIFT-1072) - Missing - (id) initWithSharedProcessor in TSharedProcessorFactory.h
+- [THRIFT-1650](https://issues.apache.org/jira/browse/THRIFT-1650) - [ruby] Update clean items and svn:ignore entries for OS X artifacts
+- [THRIFT-1661](https://issues.apache.org/jira/browse/THRIFT-1661) - [PATCH] Add --with-qt4 configure option
+- [THRIFT-1675](https://issues.apache.org/jira/browse/THRIFT-1675) - Do we have any plan to support scala?
+- [THRIFT-1645](https://issues.apache.org/jira/browse/THRIFT-1645) - Replace Object#tee with more conventional Object#tap in specs
+- [THRIFT-1644](https://issues.apache.org/jira/browse/THRIFT-1644) - Upgrade RSpec to 2.10.x and refactor specs as needed
+- [THRIFT-1672](https://issues.apache.org/jira/browse/THRIFT-1672) - MonoTouch (and Mono for Android) compatibility
+- [THRIFT-1702](https://issues.apache.org/jira/browse/THRIFT-1702) - a thrift manual
+- [THRIFT-1694](https://issues.apache.org/jira/browse/THRIFT-1694) - Re-Enable serialization for WP7 Silverlight
+- [THRIFT-1691](https://issues.apache.org/jira/browse/THRIFT-1691) - Serializer/deserializer support for Delphi
+- [THRIFT-1688](https://issues.apache.org/jira/browse/THRIFT-1688) - Update IDL page markup
+- [THRIFT-1725](https://issues.apache.org/jira/browse/THRIFT-1725) - Tutorial web pages for Delphi and C#
+- [THRIFT-1714](https://issues.apache.org/jira/browse/THRIFT-1714) - [ruby] Explicitly add CWD to Ruby test_suites.rb
+- [THRIFT-317](https://issues.apache.org/jira/browse/THRIFT-317) - Issues with Java struct validation
+- [THRIFT-164](https://issues.apache.org/jira/browse/THRIFT-164) - Build web tutorial on Incubator web site
+- [THRIFT-541](https://issues.apache.org/jira/browse/THRIFT-541) - Cocoa code generator doesn't put keywords before all arguments.
+- [THRIFT-681](https://issues.apache.org/jira/browse/THRIFT-681) - The HTML generator does not handle JavaDoc style comments very well
+
+### New Feature
+- [THRIFT-1500](https://issues.apache.org/jira/browse/THRIFT-1500) - D programming language support
+- [THRIFT-1510](https://issues.apache.org/jira/browse/THRIFT-1510) - There should be an implementation of the JsonProtocol for ruby
+- [THRIFT-1115](https://issues.apache.org/jira/browse/THRIFT-1115) - python TBase class for dynamic (de)serialization, and __slots__ option for memory savings
+- [THRIFT-1953](https://issues.apache.org/jira/browse/THRIFT-1953) - support for asp.net mvc 3
+
+### Question
+- [THRIFT-1235](https://issues.apache.org/jira/browse/THRIFT-1235) - How could I use THttpServerTransportFactory withTNonBlockingServer
+- [THRIFT-1368](https://issues.apache.org/jira/browse/THRIFT-1368) - TNonblockingServer usage
+- [THRIFT-1061](https://issues.apache.org/jira/browse/THRIFT-1061) - Read an invalid frame size of 0. Are you using TFramedTransport on the client side?
+- [THRIFT-491](https://issues.apache.org/jira/browse/THRIFT-491) - Ripping raw pthreads out of TFileTransport and associated test issues
+
+### Sub-task
+- [THRIFT-1596](https://issues.apache.org/jira/browse/THRIFT-1596) - Delphi: Test clients should have a return codes that reflect whether they succeeded or not
+- [THRIFT-982](https://issues.apache.org/jira/browse/THRIFT-982) - javame: add version Info to the library
+- [THRIFT-1722](https://issues.apache.org/jira/browse/THRIFT-1722) - C# WP7 Assembly addition beaks mono build
+- [THRIFT-336](https://issues.apache.org/jira/browse/THRIFT-336) - Compact Protocol in C#
+
+### Test
+- [THRIFT-1613](https://issues.apache.org/jira/browse/THRIFT-1613) - Add code back into empty source file ToStringTest.java
+- [THRIFT-1718](https://issues.apache.org/jira/browse/THRIFT-1718) - Incorrect check in TFileTransportTest
+
+### Wish
+- [THRIFT-1463](https://issues.apache.org/jira/browse/THRIFT-1463) - Decouple Thrift IDL from generators
+- [THRIFT-1466](https://issues.apache.org/jira/browse/THRIFT-1466) - Proper Documentation for Thrift C Glib
+- [THRIFT-1539](https://issues.apache.org/jira/browse/THRIFT-1539) - Build and distribute the fb303 python libraries along with thrift
+- [THRIFT-1685](https://issues.apache.org/jira/browse/THRIFT-1685) - Please add "aereo.com" to "Powered by Apache Thrift" list in about page
+- [THRIFT-330](https://issues.apache.org/jira/browse/THRIFT-330) - TProcessor - additional method to called when connection is broken
+
+## 0.8
+
+### Bug
+- [THRIFT-1436](https://issues.apache.org/jira/browse/THRIFT-1436) - pip install thrift fails on Windows with "Unable to find vcvarsall.bat"
+- [THRIFT-1432](https://issues.apache.org/jira/browse/THRIFT-1432) - Javascript struct constants declared in the same file as their struct definition will cause an error
+- [THRIFT-1428](https://issues.apache.org/jira/browse/THRIFT-1428) - shared.thrft does not include namespace for php, so thrift compiler generate incorrect name
+- [THRIFT-1426](https://issues.apache.org/jira/browse/THRIFT-1426) - Dist package missing files for release 0.8
+- [THRIFT-1425](https://issues.apache.org/jira/browse/THRIFT-1425) - The Node package is incompatible with latest node (0.6) & npm (1.0.27)
+- [THRIFT-1416](https://issues.apache.org/jira/browse/THRIFT-1416) - Python Unit test is broken on ci
+- [THRIFT-1419](https://issues.apache.org/jira/browse/THRIFT-1419) - AbstractNonBlockingServer does not catch errors when invoking the processor
+- [THRIFT-1424](https://issues.apache.org/jira/browse/THRIFT-1424) - Ruby specs fail when run with rake
+- [THRIFT-1420](https://issues.apache.org/jira/browse/THRIFT-1420) - Nonblocking and HsHa server should make sure to close all their socket connections when the selector exits
+- [THRIFT-1413](https://issues.apache.org/jira/browse/THRIFT-1413) - Generated code does not read MapEnd / ListEnd / SetEnd
+- [THRIFT-1409](https://issues.apache.org/jira/browse/THRIFT-1409) - Name conflict check does not work properly for exception object(Delphi).
+- [THRIFT-1408](https://issues.apache.org/jira/browse/THRIFT-1408) - Delphi Test Server: Exception test case fails due to naming conflict with e.message
+- [THRIFT-1407](https://issues.apache.org/jira/browse/THRIFT-1407) - Typo in Python socket server causes Thrift to fail when we enable a global socket timout
+- [THRIFT-1397](https://issues.apache.org/jira/browse/THRIFT-1397) - CI server fails during build due to unused parameters in delphi generator
+- [THRIFT-1404](https://issues.apache.org/jira/browse/THRIFT-1404) - Delphi compiler generates struct reader code with problem.
+- [THRIFT-1400](https://issues.apache.org/jira/browse/THRIFT-1400) - Ruby native extension aborts with __stack_chk_fail in OSX
+- [THRIFT-1399](https://issues.apache.org/jira/browse/THRIFT-1399) - One of the TServerImpl.Create CTORs lacks implementation
+- [THRIFT-1390](https://issues.apache.org/jira/browse/THRIFT-1390) - Debian packages build fix for Squeeze (build from the official 0.7.0 tarball)
+- [THRIFT-1393](https://issues.apache.org/jira/browse/THRIFT-1393) - TTransportException's thrown from THttpClient contain superfluous slashes in the Exception message
+- [THRIFT-1392](https://issues.apache.org/jira/browse/THRIFT-1392) - Enabling both namespaces and autoloading in generated PHP code won't work.
+- [THRIFT-1406](https://issues.apache.org/jira/browse/THRIFT-1406) - Build error after applying THRIFT-1395
+- [THRIFT-1405](https://issues.apache.org/jira/browse/THRIFT-1405) - Delphi compiler does not generates container serializer properly.
+- [THRIFT-1411](https://issues.apache.org/jira/browse/THRIFT-1411) - java generator does not provide type parameter for TBaseProcessor
+- [THRIFT-1473](https://issues.apache.org/jira/browse/THRIFT-1473) - JSON context stack may be left in an incorrect state when an exception is thrown during read or write operations
+- [THRIFT-1331](https://issues.apache.org/jira/browse/THRIFT-1331) - Ruby library deserializes an empty map to nil
+- [THRIFT-1330](https://issues.apache.org/jira/browse/THRIFT-1330) - PHP Namespaces no longer generated
+- [THRIFT-1328](https://issues.apache.org/jira/browse/THRIFT-1328) - TBaseHelper.toString(...) appends ByteBuffer data outside of valid buffer range
+- [THRIFT-1322](https://issues.apache.org/jira/browse/THRIFT-1322) - OCaml lib fail to compile: Thrift.ml line 305, int vs int32 mismatch
+- [THRIFT-1143](https://issues.apache.org/jira/browse/THRIFT-1143) - Build doesn't detect correct architecture type on 64bit osx
+- [THRIFT-1205](https://issues.apache.org/jira/browse/THRIFT-1205) - port server unduly fragile with arbitrary input
+- [THRIFT-1279](https://issues.apache.org/jira/browse/THRIFT-1279) - type set is handled incorrectly when writing object
+- [THRIFT-1298](https://issues.apache.org/jira/browse/THRIFT-1298) - Standard scheme doesn't read or write metadata along with field values
+- [THRIFT-1265](https://issues.apache.org/jira/browse/THRIFT-1265) - C++ container deserialize
+- [THRIFT-1263](https://issues.apache.org/jira/browse/THRIFT-1263) - publish ruby client to rubygems
+- [THRIFT-1384](https://issues.apache.org/jira/browse/THRIFT-1384) - Java help menu missing newline near javame flag
+- [THRIFT-1382](https://issues.apache.org/jira/browse/THRIFT-1382) - Bundle install doesnot work because thrift crashes
+- [THRIFT-1381](https://issues.apache.org/jira/browse/THRIFT-1381) - Thrift C++ libs have incorrectly versioned names
+- [THRIFT-1350](https://issues.apache.org/jira/browse/THRIFT-1350) - Go library code does not build as of r60 (most recent release)
+- [THRIFT-1365](https://issues.apache.org/jira/browse/THRIFT-1365) - TupleProtocol#writeBitSet unintentionally writes a variable length byte array
+- [THRIFT-1359](https://issues.apache.org/jira/browse/THRIFT-1359) - --gen-cob cpp:cob_style does not compile anymore
+- [THRIFT-1319](https://issues.apache.org/jira/browse/THRIFT-1319) - Mismatch between how a union reads and writes a container
+- [THRIFT-1309](https://issues.apache.org/jira/browse/THRIFT-1309) - libfb303-0.7.0.jar missing in maven repository
+- [THRIFT-1238](https://issues.apache.org/jira/browse/THRIFT-1238) - Thrift JS client cannot read map of structures
+- [THRIFT-1254](https://issues.apache.org/jira/browse/THRIFT-1254) - Code can't be compiled against a regular JRE: Object.clone() override has a different return type
+- [THRIFT-1367](https://issues.apache.org/jira/browse/THRIFT-1367) - Mac OSX build fails with "no such file to load -- spec/rake/spectask"
+- [THRIFT-1355](https://issues.apache.org/jira/browse/THRIFT-1355) - Running make in lib/rb doesn't build the native extensions
+- [THRIFT-1370](https://issues.apache.org/jira/browse/THRIFT-1370) - Debian packaging should Build-Depend on libglib2.0-dev
+- [THRIFT-1342](https://issues.apache.org/jira/browse/THRIFT-1342) - Compilation problem on Windows of fastbinary.c
+- [THRIFT-1341](https://issues.apache.org/jira/browse/THRIFT-1341) - TProtocol.h endian detection wrong with boost
+- [THRIFT-1583](https://issues.apache.org/jira/browse/THRIFT-1583) - c_glib leaks memory
+- [THRIFT-1582](https://issues.apache.org/jira/browse/THRIFT-1582) - Bad includes of nested thrift files in c_glib
+- [THRIFT-1578](https://issues.apache.org/jira/browse/THRIFT-1578) - C_GLib generated code does not compile
+- [THRIFT-1027](https://issues.apache.org/jira/browse/THRIFT-1027) - 'make -j 16' fails with "unterminated #ifdef" error
+- [THRIFT-1121](https://issues.apache.org/jira/browse/THRIFT-1121) - Java server performance regression in 0.6
+- [THRIFT-857](https://issues.apache.org/jira/browse/THRIFT-857) - tests run by "make install" fail if generators are disabled
+- [THRIFT-380](https://issues.apache.org/jira/browse/THRIFT-380) - Use setuptools for python build
+
+### Dependency upgrade
+- [THRIFT-1257](https://issues.apache.org/jira/browse/THRIFT-1257) - thrift's dependency scope on javax.servlet:servlet-api should be 'provided'
+
+### Improvement
+- [THRIFT-1445](https://issues.apache.org/jira/browse/THRIFT-1445) - minor C++ generator variable cleanup
+- [THRIFT-1435](https://issues.apache.org/jira/browse/THRIFT-1435) - make TException.Message property conformant to the usual expectations
+- [THRIFT-1431](https://issues.apache.org/jira/browse/THRIFT-1431) - Rename 'sys' module to 'util'
+- [THRIFT-1396](https://issues.apache.org/jira/browse/THRIFT-1396) - Dephi generator has dependacy on boost 1.42 later.
+- [THRIFT-1395](https://issues.apache.org/jira/browse/THRIFT-1395) - Patch to prevent warnings for integer types in some cases
+- [THRIFT-1275](https://issues.apache.org/jira/browse/THRIFT-1275) - thrift: always prefix namespaces with " ::"
+- [THRIFT-1274](https://issues.apache.org/jira/browse/THRIFT-1274) - thrift: fail compilation if an unexpected token is
+- [THRIFT-1271](https://issues.apache.org/jira/browse/THRIFT-1271) - thrift: fix missing namespace in generated local
+- [THRIFT-1270](https://issues.apache.org/jira/browse/THRIFT-1270) - thrift: add --allow-neg-keys argument to allow
+- [THRIFT-1345](https://issues.apache.org/jira/browse/THRIFT-1345) - Allow building without tests
+- [THRIFT-1286](https://issues.apache.org/jira/browse/THRIFT-1286) - Modernize the Thrift Ruby Library Dev Environment
+- [THRIFT-1284](https://issues.apache.org/jira/browse/THRIFT-1284) - thrift: fix processor inheritance
+- [THRIFT-1283](https://issues.apache.org/jira/browse/THRIFT-1283) - thrift: wrap t_cpp_generator::generate_process_function() to 80
+- [THRIFT-1282](https://issues.apache.org/jira/browse/THRIFT-1282) - Upgrade httpclient to 4.1.2 (from 4.0.1)
+- [THRIFT-1281](https://issues.apache.org/jira/browse/THRIFT-1281) - add @generated to the docblock
+- [THRIFT-1280](https://issues.apache.org/jira/browse/THRIFT-1280) - Thrift: Improve Monitor exception-free interfaces
+- [THRIFT-1278](https://issues.apache.org/jira/browse/THRIFT-1278) - javadoc warnings - compilation
+- [THRIFT-1227](https://issues.apache.org/jira/browse/THRIFT-1227) - Erlang implementation of thrift JSON protocol
+- [THRIFT-1295](https://issues.apache.org/jira/browse/THRIFT-1295) - Duplicate include in TSocket.cpp
+- [THRIFT-1294](https://issues.apache.org/jira/browse/THRIFT-1294) - thrift: fix log message typos in TSimpleServer
+- [THRIFT-1293](https://issues.apache.org/jira/browse/THRIFT-1293) - thrift: improve handling of exceptions thrown by
+- [THRIFT-1292](https://issues.apache.org/jira/browse/THRIFT-1292) - thrift: silence log spew from TThreadedServer
+- [THRIFT-1288](https://issues.apache.org/jira/browse/THRIFT-1288) - Allow typedefed exceptions in throws clauses
+- [THRIFT-1290](https://issues.apache.org/jira/browse/THRIFT-1290) - thrift: TNonblockingServer: clean up state in the
+- [THRIFT-1287](https://issues.apache.org/jira/browse/THRIFT-1287) - thrift: start refactoring some of the C++ processor
+- [THRIFT-1289](https://issues.apache.org/jira/browse/THRIFT-1289) - thrift: implement TNonblockingServer::stop()
+- [THRIFT-1305](https://issues.apache.org/jira/browse/THRIFT-1305) - thrift: make TConnection a private inner class of
+- [THRIFT-1304](https://issues.apache.org/jira/browse/THRIFT-1304) - TNonblockingServer: pass in the connection context to
+- [THRIFT-1302](https://issues.apache.org/jira/browse/THRIFT-1302) - thrift: raise an exception if send() times out in
+- [THRIFT-1301](https://issues.apache.org/jira/browse/THRIFT-1301) - thrift: consolidate common code in TNonblockingServer
+- [THRIFT-1377](https://issues.apache.org/jira/browse/THRIFT-1377) - abort PHP deserialization on unknown field type
+- [THRIFT-1379](https://issues.apache.org/jira/browse/THRIFT-1379) - fix uninitialized enum values in thrift C++ objects
+- [THRIFT-1376](https://issues.apache.org/jira/browse/THRIFT-1376) - Make port specification option in thrift remote
+- [THRIFT-1375](https://issues.apache.org/jira/browse/THRIFT-1375) - fixed a hex char conversion bug in TJSONProtocol
+- [THRIFT-1373](https://issues.apache.org/jira/browse/THRIFT-1373) - Fix user-defined exception generation in thrift (python)
+- [THRIFT-1361](https://issues.apache.org/jira/browse/THRIFT-1361) - Optional replacement of pthread by boost::thread
+- [THRIFT-1320](https://issues.apache.org/jira/browse/THRIFT-1320) - Consistency of configure generated config.h
+- [THRIFT-1317](https://issues.apache.org/jira/browse/THRIFT-1317) - Remove copy constructibility from
+- [THRIFT-1316](https://issues.apache.org/jira/browse/THRIFT-1316) - thrift: update server classes to accept
+- [THRIFT-1315](https://issues.apache.org/jira/browse/THRIFT-1315) - thrift: generate server interface factory classes
+- [THRIFT-1314](https://issues.apache.org/jira/browse/THRIFT-1314) - thrift: add TProcessorFactory
+- [THRIFT-1335](https://issues.apache.org/jira/browse/THRIFT-1335) - Add accept timeout to TServerSocket
+- [THRIFT-1334](https://issues.apache.org/jira/browse/THRIFT-1334) - Add more info to IllegalStateException
+- [THRIFT-1333](https://issues.apache.org/jira/browse/THRIFT-1333) - Make RWGuard not copyable
+- [THRIFT-1332](https://issues.apache.org/jira/browse/THRIFT-1332) - TSSLTransportParameters class uses hard coded value keyManagerType: SunX509
+- [THRIFT-1251](https://issues.apache.org/jira/browse/THRIFT-1251) - Generated java code should indicate which fields are required and which are optional
+- [THRIFT-1387](https://issues.apache.org/jira/browse/THRIFT-1387) - Build MSVC libraries with Boost Threads instead of Pthreads
+- [THRIFT-1339](https://issues.apache.org/jira/browse/THRIFT-1339) - Extend Tuple Protocol to TUnions
+- [THRIFT-1031](https://issues.apache.org/jira/browse/THRIFT-1031) - Patch to compile Thrift for vc++ 9.0 and 10.0
+- [THRIFT-1130](https://issues.apache.org/jira/browse/THRIFT-1130) - Add the ability to specify symbolic default value for optional boolean
+- [THRIFT-1123](https://issues.apache.org/jira/browse/THRIFT-1123) - Patch to compile Thrift server and client for vc++ 9.0 and 10.0
+- [THRIFT-386](https://issues.apache.org/jira/browse/THRIFT-386) - Make it possible to build the Python library without the extension
+
+### New Feature
+- [THRIFT-1401](https://issues.apache.org/jira/browse/THRIFT-1401) - JSON-protocol for Delphi XE Libraries
+- [THRIFT-1167](https://issues.apache.org/jira/browse/THRIFT-1167) - Java nonblocking server with more than one thread for select and handling IO
+- [THRIFT-1366](https://issues.apache.org/jira/browse/THRIFT-1366) - Delphi generator, lirbrary and unit test.
+- [THRIFT-1354](https://issues.apache.org/jira/browse/THRIFT-1354) - Add rake task to build just the gem file
+- [THRIFT-769](https://issues.apache.org/jira/browse/THRIFT-769) - Pluggable Serializers
+
+### Sub-task
+- [THRIFT-1415](https://issues.apache.org/jira/browse/THRIFT-1415) - delphi: add version Info to the library
+- [THRIFT-1391](https://issues.apache.org/jira/browse/THRIFT-1391) - Improved Delphi XE test cases
+
+## 0.7
+
+### Bug
+- [THRIFT-1140](https://issues.apache.org/jira/browse/THRIFT-1140) - Framed Transport Client using C (Glib) Library hangs when connecting to Ruby Server
+- [THRIFT-1154](https://issues.apache.org/jira/browse/THRIFT-1154) - HttpClient does not specify the connection close parameter
+- [THRIFT-1153](https://issues.apache.org/jira/browse/THRIFT-1153) - HttpClient does not specify the connection close parameter
+- [THRIFT-1149](https://issues.apache.org/jira/browse/THRIFT-1149) - Nonblocking server fails when client connection is reset
+- [THRIFT-1146](https://issues.apache.org/jira/browse/THRIFT-1146) - Android Incompatibility : in Android < 2.3 java.io.IOException doesn't support for Throwable parameter in constructor
+- [THRIFT-1133](https://issues.apache.org/jira/browse/THRIFT-1133) - Java and JavaScript tutorial is broken since we have Java maven deployment
+- [THRIFT-1132](https://issues.apache.org/jira/browse/THRIFT-1132) - Deserialization error in TApplicationException C#
+- [THRIFT-1131](https://issues.apache.org/jira/browse/THRIFT-1131) - C# JSON Protocol is unable to decode escaped characters in string
+- [THRIFT-1208](https://issues.apache.org/jira/browse/THRIFT-1208) - python TCompactProtocol.py writeBool and readBool not follow the compact-proto-spec-2.txt spec for CONTAINER_WRITE, CONTAINER_READ
+- [THRIFT-1200](https://issues.apache.org/jira/browse/THRIFT-1200) - JS compiler generates code that clobbers existing namespaces
+- [THRIFT-1183](https://issues.apache.org/jira/browse/THRIFT-1183) - Pure-ruby CompactProtocol raises ArgumentError when deserializing under Ruby 1.9
+- [THRIFT-1182](https://issues.apache.org/jira/browse/THRIFT-1182) - Native deserializer segfaults on incorrect list element type
+- [THRIFT-1181](https://issues.apache.org/jira/browse/THRIFT-1181) - AS3 compiler generates incorrect code for setting default values in constructor
+- [THRIFT-1234](https://issues.apache.org/jira/browse/THRIFT-1234) - thrift --help is missing doc on py:utf8strings
+- [THRIFT-1180](https://issues.apache.org/jira/browse/THRIFT-1180) - AS3 compiler generates uncompilable code for binary types.
+- [THRIFT-1194](https://issues.apache.org/jira/browse/THRIFT-1194) - Java lib does not install artifacts to local dir correctly
+- [THRIFT-1193](https://issues.apache.org/jira/browse/THRIFT-1193) - Potential infinite loop in nonblocking_server
+- [THRIFT-1192](https://issues.apache.org/jira/browse/THRIFT-1192) - Typo: TProtocol.h tests for HAVE_SYS_PARAM_H_
+- [THRIFT-1190](https://issues.apache.org/jira/browse/THRIFT-1190) - readBufferBytesAllocated in TNonblockingServer.java should be AtomicLong to fix FD leakage and general server malfunction
+- [THRIFT-1187](https://issues.apache.org/jira/browse/THRIFT-1187) - nonblocking_server shutdown race under Ruby 1.9
+- [THRIFT-1178](https://issues.apache.org/jira/browse/THRIFT-1178) - Java: TBase signature should be T extends TBase<?,?>
+- [THRIFT-1164](https://issues.apache.org/jira/browse/THRIFT-1164) - Segmentation fault on NULL pointer in t_js_generator::generate_const
+- [THRIFT-1171](https://issues.apache.org/jira/browse/THRIFT-1171) - Perl write/readDouble assumes little-endian platform
+- [THRIFT-1222](https://issues.apache.org/jira/browse/THRIFT-1222) - Unhandled exception for TEvhttpServer request
+- [THRIFT-1220](https://issues.apache.org/jira/browse/THRIFT-1220) - TProcessor::process never returns false
+- [THRIFT-1285](https://issues.apache.org/jira/browse/THRIFT-1285) - Stable 0.7.0 Windows compiler exe available on the webside is not the good one
+- [THRIFT-1218](https://issues.apache.org/jira/browse/THRIFT-1218) - c_glib uses wrong name in pkg-config
+- [THRIFT-1215](https://issues.apache.org/jira/browse/THRIFT-1215) - Undefined property Thirft in lib/js/thrift.js
+- [THRIFT-1211](https://issues.apache.org/jira/browse/THRIFT-1211) - When using THttpClient, non 200 responses leave the connection open
+- [THRIFT-1228](https://issues.apache.org/jira/browse/THRIFT-1228) - The php accelerator module calls flush incorrectly
+- [THRIFT-1308](https://issues.apache.org/jira/browse/THRIFT-1308) - libfb303-0.7.0.jar missing in maven repository
+- [THRIFT-1255](https://issues.apache.org/jira/browse/THRIFT-1255) - Mismatch of method name between JavaME's lib and generated code (compareTo/compareObjects)
+- [THRIFT-1253](https://issues.apache.org/jira/browse/THRIFT-1253) - Code generated for maps is not compiling
+- [THRIFT-1252](https://issues.apache.org/jira/browse/THRIFT-1252) - Segfault in Ruby deserializer
+- [THRIFT-1094](https://issues.apache.org/jira/browse/THRIFT-1094) - bug in TCompactProto python readMessageEnd method and updated test cases
+- [THRIFT-1093](https://issues.apache.org/jira/browse/THRIFT-1093) - several bugs in python TCompactProtocol
+- [THRIFT-1092](https://issues.apache.org/jira/browse/THRIFT-1092) - generated validate() method has wrong indentation
+- [THRIFT-1011](https://issues.apache.org/jira/browse/THRIFT-1011) - Error generating package imports when using classes from other packages
+- [THRIFT-1050](https://issues.apache.org/jira/browse/THRIFT-1050) - Declaring an argument named "manager" to a service method produces code that fails compile due to name conflicts with protected ivars in TAsyncClient
+- [THRIFT-1074](https://issues.apache.org/jira/browse/THRIFT-1074) - .keystore and .truststore are missing from the 0.6.0 distribution
+- [THRIFT-1067](https://issues.apache.org/jira/browse/THRIFT-1067) - Tons of bugs in php implementation
+- [THRIFT-1065](https://issues.apache.org/jira/browse/THRIFT-1065) - Unexpected exceptions not proper handled on JS
+- [THRIFT-1076](https://issues.apache.org/jira/browse/THRIFT-1076) - Erlang Thrift socket server has a bug that causes java thrift client of framed binary client to throw "out of sequence" exception
+- [THRIFT-1057](https://issues.apache.org/jira/browse/THRIFT-1057) - casts in TBinaryProtocol.tcc causing "dereferencing type-punned pointer will break strict-aliasing rules" warnings from gcc
+- [THRIFT-1055](https://issues.apache.org/jira/browse/THRIFT-1055) - csharp TServerSocket and TSocket do not disable Nagle via Socket.NoDelay = true like cpp and java do
+- [THRIFT-1054](https://issues.apache.org/jira/browse/THRIFT-1054) - explicit call to PKG_PROG_PKG_CONFIG is missing and first use of PKG_CHECK_MODULES may not happen, causes mono detection to fail
+- [THRIFT-1117](https://issues.apache.org/jira/browse/THRIFT-1117) - JavaScript Unit Test does not work anymore because libthrift*.jar where moved by Maven Deployment
+- [THRIFT-1111](https://issues.apache.org/jira/browse/THRIFT-1111) - The HTML generator does not distinguish between string and binary types
+- [THRIFT-1032](https://issues.apache.org/jira/browse/THRIFT-1032) - "make dist" fails due to c_glib problem
+- [THRIFT-1036](https://issues.apache.org/jira/browse/THRIFT-1036) - Auto-generated C++ code fails to compile with "-Werror -Wextra -Wall" g++ compiler flags
+- [THRIFT-1041](https://issues.apache.org/jira/browse/THRIFT-1041) - TDeserializer holds onto a reference of the array it reads after it is done deserializing
+- [THRIFT-1106](https://issues.apache.org/jira/browse/THRIFT-1106) - C++ code TAsyncProtocolProcessor.h & TAsyncBufferProcessor.h dont have virtual functions but no virtual destructor. Causes warnings on -Wall
+- [THRIFT-1105](https://issues.apache.org/jira/browse/THRIFT-1105) - OCaml generator does not prefix methods of included structs with their type
+- [THRIFT-1104](https://issues.apache.org/jira/browse/THRIFT-1104) - INSTALLDIRS should be included in configure script
+- [THRIFT-1102](https://issues.apache.org/jira/browse/THRIFT-1102) - typo in configure.ac: "==" operator in 'test' (instead of"'=")
+- [THRIFT-1101](https://issues.apache.org/jira/browse/THRIFT-1101) - bytebuffer length calculation in TBinaryProtocol writeBinary
+- [THRIFT-1098](https://issues.apache.org/jira/browse/THRIFT-1098) - Undefined properties in TBinaryProtocolFactory
+- [THRIFT-1081](https://issues.apache.org/jira/browse/THRIFT-1081) - PHP tests broken and somewhat incomplete
+- [THRIFT-1080](https://issues.apache.org/jira/browse/THRIFT-1080) - erlang test's 'make' fails on Mac OSX
+- [THRIFT-1078](https://issues.apache.org/jira/browse/THRIFT-1078) - ThriftTest.thrift generates invalid PHP library
+- [THRIFT-1120](https://issues.apache.org/jira/browse/THRIFT-1120) - proto.WriteListEnd being called in the wrong place
+- [THRIFT-1119](https://issues.apache.org/jira/browse/THRIFT-1119) - TJSONProtocol fails to UTF8 decode strings
+- [THRIFT-867](https://issues.apache.org/jira/browse/THRIFT-867) - PHP accelerator module's output transport is incompatible with TFramedTransport
+- [THRIFT-826](https://issues.apache.org/jira/browse/THRIFT-826) - PHP TSocket Write Timeout
+- [THRIFT-835](https://issues.apache.org/jira/browse/THRIFT-835) - Bad AS3 syntax in constructors that set default values
+- [THRIFT-788](https://issues.apache.org/jira/browse/THRIFT-788) - thrift_protocol.so: multiget/multiget_slice does not handle more than 17 keys correctly
+- [THRIFT-125](https://issues.apache.org/jira/browse/THRIFT-125) - OCaml libraries don't compile with 32-bit ocaml
+- [THRIFT-342](https://issues.apache.org/jira/browse/THRIFT-342) - PHP: can't have sets of complex types
+- [THRIFT-731](https://issues.apache.org/jira/browse/THRIFT-731) - configure doesn't check for ant >= 1.7
+- [THRIFT-690](https://issues.apache.org/jira/browse/THRIFT-690) - Update TApplicationException codes
+- [THRIFT-638](https://issues.apache.org/jira/browse/THRIFT-638) - BufferedTransport + C extensions block until recv timeout is reached on last fread call
+
+### Dependency upgrade
+- [THRIFT-1177](https://issues.apache.org/jira/browse/THRIFT-1177) - Update thrift to reflect changes in Go's networking libraries
+
+### Improvement
+- [THRIFT-1155](https://issues.apache.org/jira/browse/THRIFT-1155) - Remove log4j dependency from java client
+- [THRIFT-1151](https://issues.apache.org/jira/browse/THRIFT-1151) - Produce more informative runtime error in case of schema and data mismatch during serialization
+- [THRIFT-1207](https://issues.apache.org/jira/browse/THRIFT-1207) - Support DESTDIR on "make install" of ruby libs
+- [THRIFT-1199](https://issues.apache.org/jira/browse/THRIFT-1199) - Union structs should have generated methods to test whether a specific field is currently set
+- [THRIFT-1233](https://issues.apache.org/jira/browse/THRIFT-1233) - Remove unused include in generated C++ code
+- [THRIFT-1189](https://issues.apache.org/jira/browse/THRIFT-1189) - Ruby deserializer speed improvements
+- [THRIFT-1170](https://issues.apache.org/jira/browse/THRIFT-1170) - Thrift Generated Code and Java 5
+- [THRIFT-1174](https://issues.apache.org/jira/browse/THRIFT-1174) - Publish as3 client implementation via Maven for use by flex-mojos users
+- [THRIFT-1225](https://issues.apache.org/jira/browse/THRIFT-1225) - TCompactProtocol for PHP
+- [THRIFT-1221](https://issues.apache.org/jira/browse/THRIFT-1221) - Remove SimpleCallback.h
+- [THRIFT-1217](https://issues.apache.org/jira/browse/THRIFT-1217) - Use evutil_socketpair instead of pipe (Windows port)
+- [THRIFT-1216](https://issues.apache.org/jira/browse/THRIFT-1216) - build Java Library behind a proxy
+- [THRIFT-1231](https://issues.apache.org/jira/browse/THRIFT-1231) - Remove bogus include
+- [THRIFT-1213](https://issues.apache.org/jira/browse/THRIFT-1213) - Membuffer should provide a way to get back the buffer
+- [THRIFT-1237](https://issues.apache.org/jira/browse/THRIFT-1237) - Java fb303 missing some methods
+- [THRIFT-1063](https://issues.apache.org/jira/browse/THRIFT-1063) - Fix Erlang Tutorial Files
+- [THRIFT-1053](https://issues.apache.org/jira/browse/THRIFT-1053) - Make remote client's IP address available for all socket related transports
+- [THRIFT-1109](https://issues.apache.org/jira/browse/THRIFT-1109) - Deploy fb303 along side libthrift to maven repo
+- [THRIFT-1107](https://issues.apache.org/jira/browse/THRIFT-1107) - improvement for compiler-generated python for 'None' object comparisons
+- [THRIFT-1069](https://issues.apache.org/jira/browse/THRIFT-1069) - Add command line option to prevent thrift from inserting gen-* directories
+- [THRIFT-1049](https://issues.apache.org/jira/browse/THRIFT-1049) - Allow for TServerSocket python library to bind to a specific host
+- [THRIFT-1126](https://issues.apache.org/jira/browse/THRIFT-1126) - Extending struct_info for erlang bindings
+- [THRIFT-1100](https://issues.apache.org/jira/browse/THRIFT-1100) - python TSSLSocket improvements, including certificate validation
+- [THRIFT-994](https://issues.apache.org/jira/browse/THRIFT-994) - Don't try to invoke phpize if we don't have it
+- [THRIFT-993](https://issues.apache.org/jira/browse/THRIFT-993) - Some improvements in C++ stubs for oneway operations
+- [THRIFT-997](https://issues.apache.org/jira/browse/THRIFT-997) - Using valueOf for base types in getFieldValue
+- [THRIFT-418](https://issues.apache.org/jira/browse/THRIFT-418) - Don't do runtime sorting of struct fields
+- [THRIFT-151](https://issues.apache.org/jira/browse/THRIFT-151) - TSSLServerSocket and TSSLSocket implementation
+- [THRIFT-27](https://issues.apache.org/jira/browse/THRIFT-27) - Generated erlang types don't contain default values for records
+- [THRIFT-113](https://issues.apache.org/jira/browse/THRIFT-113) - to-string methods should omit optional null fields from output
+- [THRIFT-363](https://issues.apache.org/jira/browse/THRIFT-363) - Maven Deploy
+- [THRIFT-447](https://issues.apache.org/jira/browse/THRIFT-447) - Make an abstract base Client class so we can generate less code
+- [THRIFT-627](https://issues.apache.org/jira/browse/THRIFT-627) - should c++ have setters for optional fields?
+
+### New Feature
+- [THRIFT-1236](https://issues.apache.org/jira/browse/THRIFT-1236) - Erlang Reconnecting Thrift Client
+- [THRIFT-1021](https://issues.apache.org/jira/browse/THRIFT-1021) - Framed transport support for OCaml
+- [THRIFT-1068](https://issues.apache.org/jira/browse/THRIFT-1068) - Python SSL Socket Support
+- [THRIFT-1103](https://issues.apache.org/jira/browse/THRIFT-1103) - TZlibTransport for python, a zlib compressed transport
+- [THRIFT-1083](https://issues.apache.org/jira/browse/THRIFT-1083) - Preforking python process pool server
+- [THRIFT-999](https://issues.apache.org/jira/browse/THRIFT-999) - Add TForkingServer
+
+### Sub-task
+- [THRIFT-1152](https://issues.apache.org/jira/browse/THRIFT-1152) - Attributes from private to protected
+- [THRIFT-1038](https://issues.apache.org/jira/browse/THRIFT-1038) - Generated Java code for structures containing binary fields (or collections thereof) are not serializable (in the Java sense) even though they implement java.io.Serializable
+
+### Task
+- [THRIFT-892](https://issues.apache.org/jira/browse/THRIFT-892) - Refactor erlang build system with rebar
+
+### Wish
+- [THRIFT-625](https://issues.apache.org/jira/browse/THRIFT-625) - Add support for 'Go'
+
+## 0.6.1
+
+### Bug
+- [THRIFT-1133](https://issues.apache.org/jira/browse/THRIFT-1133) - Java and JavaScript tutorial is broken since we have Java maven deployment
+- [THRIFT-1131](https://issues.apache.org/jira/browse/THRIFT-1131) - C# JSON Protocol is unable to decode escaped characters in string
+- [THRIFT-1074](https://issues.apache.org/jira/browse/THRIFT-1074) - .keystore and .truststore are missing from the 0.6.0 distribution
+
+### Improvement
+- [THRIFT-1109](https://issues.apache.org/jira/browse/THRIFT-1109) - Deploy fb303 along side libthrift to maven repo
+- [THRIFT-363](https://issues.apache.org/jira/browse/THRIFT-363) - Maven Deploy
+
+### Question
+- [THRIFT-1206](https://issues.apache.org/jira/browse/THRIFT-1206) - did the THRIFT 0.6.1 merge THRIFT-563 ?
+
+### Sub-task
+- [THRIFT-1163](https://issues.apache.org/jira/browse/THRIFT-1163) - How can i use multi service in one program?
+
+### Task
+- [THRIFT-1112](https://issues.apache.org/jira/browse/THRIFT-1112) - Apply THRIFT-363 to 0.6 branch
+- [THRIFT-1113](https://issues.apache.org/jira/browse/THRIFT-1113) - Apply THRIFT-1074 to 0.6 branch
+
+## 0.6
+
+### Bug
+- [THRIFT-1020](https://issues.apache.org/jira/browse/THRIFT-1020) - OCaml compiler generates invalid OCaml
+- [THRIFT-1015](https://issues.apache.org/jira/browse/THRIFT-1015) - TUnion does not handle ByteBuffer in toString
+- [THRIFT-1013](https://issues.apache.org/jira/browse/THRIFT-1013) - generated java code may have name clashes with thrift library
+- [THRIFT-1009](https://issues.apache.org/jira/browse/THRIFT-1009) - TUnion does not correctly deep copy a ByteBuffer
+- [THRIFT-1032](https://issues.apache.org/jira/browse/THRIFT-1032) - "make dist" fails due to c_glib problem
+- [THRIFT-868](https://issues.apache.org/jira/browse/THRIFT-868) - Referencing constant values doesn't work with with typedef types
+- [THRIFT-971](https://issues.apache.org/jira/browse/THRIFT-971) - java module can't be compiled without ivy and network connection
+- [THRIFT-970](https://issues.apache.org/jira/browse/THRIFT-970) - Under heavy load, THttpClient may fail with "too many open files"
+- [THRIFT-969](https://issues.apache.org/jira/browse/THRIFT-969) - Java Tutorial broken, move CalculatorHandler to a separate file
+- [THRIFT-807](https://issues.apache.org/jira/browse/THRIFT-807) - JavaScript: Initialization of Base Types with 0 instead of null
+- [THRIFT-955](https://issues.apache.org/jira/browse/THRIFT-955) - Thrift compiler for Windows uses lowercase names and directories which is inconsistent with compiling on other platforms
+- [THRIFT-992](https://issues.apache.org/jira/browse/THRIFT-992) - Naming convention in C# constructor is not consistent with other fields causes compile errors
+- [THRIFT-1008](https://issues.apache.org/jira/browse/THRIFT-1008) - byte[] accessors throw NPE on unset field
+- [THRIFT-1006](https://issues.apache.org/jira/browse/THRIFT-1006) - Impossible to correctly qualify an enum constant in an external thrift file
+- [THRIFT-950](https://issues.apache.org/jira/browse/THRIFT-950) - Haskell bindings treat 'byte' as unsigned 8-bit int (Data.Word.Word8), java/cpp as signed (byte/int8_t).
+- [THRIFT-975](https://issues.apache.org/jira/browse/THRIFT-975) - lib/c_glib/README is missing => breaks make dist
+- [THRIFT-944](https://issues.apache.org/jira/browse/THRIFT-944) - Support all version-4s of base
+- [THRIFT-939](https://issues.apache.org/jira/browse/THRIFT-939) - optional binary fields throw NPE on default byte[] getters
+- [THRIFT-935](https://issues.apache.org/jira/browse/THRIFT-935) - PHP Extension aborts the build if php-config is not installed
+- [THRIFT-933](https://issues.apache.org/jira/browse/THRIFT-933) - Haskell's Thrift.cabal has warnings
+- [THRIFT-932](https://issues.apache.org/jira/browse/THRIFT-932) - Haskell tests need to be run through 'make check' (and probably 'cabal check') too
+- [THRIFT-904](https://issues.apache.org/jira/browse/THRIFT-904) - C# TSocket should disable nagle and linger
+- [THRIFT-941](https://issues.apache.org/jira/browse/THRIFT-941) - Make PHP C Extension use the defined Protocol writeMessageBegin function
+- [THRIFT-940](https://issues.apache.org/jira/browse/THRIFT-940) - 'make check' fails if boost is not in the std include and link paths
+- [THRIFT-924](https://issues.apache.org/jira/browse/THRIFT-924) - Fix generated php structure constants
+- [THRIFT-979](https://issues.apache.org/jira/browse/THRIFT-979) - ruby bindings used to work on jruby
+- [THRIFT-977](https://issues.apache.org/jira/browse/THRIFT-977) - Hex Conversion Bug in C++ TJSONProtocol
+- [THRIFT-347](https://issues.apache.org/jira/browse/THRIFT-347) - PHP TSocket Timeout Issues
+- [THRIFT-517](https://issues.apache.org/jira/browse/THRIFT-517) - TExceptions thrown by server result in cryptic error message on client - Tried to read 4 bytes, but only got 0 bytes
+
+### Improvement
+- [THRIFT-1024](https://issues.apache.org/jira/browse/THRIFT-1024) - Add Python Twisted example to the Tutorial
+- [THRIFT-958](https://issues.apache.org/jira/browse/THRIFT-958) - Change accessmodifer on trans_ field in the FrameBuffer class to public.
+- [THRIFT-957](https://issues.apache.org/jira/browse/THRIFT-957) - THsHaServer: Change access modifier of the invoker field.
+- [THRIFT-1002](https://issues.apache.org/jira/browse/THRIFT-1002) - CodeStyle: t_c_glib_generator.cc
+- [THRIFT-1005](https://issues.apache.org/jira/browse/THRIFT-1005) - Give unions byte[] signature methods to go along with their ByteBuffer counterparts
+- [THRIFT-951](https://issues.apache.org/jira/browse/THRIFT-951) - Add a new isServing() method to TServer
+- [THRIFT-943](https://issues.apache.org/jira/browse/THRIFT-943) - Silly readme typo fix.
+- [THRIFT-961](https://issues.apache.org/jira/browse/THRIFT-961) - JavaScript TestSuite using ant/ivy and Java's ServerTestBase Handler
+- [THRIFT-960](https://issues.apache.org/jira/browse/THRIFT-960) - add TestServer, TestNonblockingServer and TestClient again
+- [THRIFT-949](https://issues.apache.org/jira/browse/THRIFT-949) - Modify the TEnum interface so it defines a method similar to findByValue
+- [THRIFT-946](https://issues.apache.org/jira/browse/THRIFT-946) - Augment FieldValueMetaData so it differentiates 'string' and 'binary' fields.
+- [THRIFT-903](https://issues.apache.org/jira/browse/THRIFT-903) - custom ThreadFactory in THsHaServer
+- [THRIFT-913](https://issues.apache.org/jira/browse/THRIFT-913) - Test Case for Url encoded strings + simple enhancement to lib/js/test/RunTestServer.sh
+- [THRIFT-926](https://issues.apache.org/jira/browse/THRIFT-926) - Miscellaneous C++ improvements
+- [THRIFT-929](https://issues.apache.org/jira/browse/THRIFT-929) - Improvements to the C++ test suite
+- [THRIFT-893](https://issues.apache.org/jira/browse/THRIFT-893) - add JavaScript to the tutorial examples
+- [THRIFT-1003](https://issues.apache.org/jira/browse/THRIFT-1003) - Polishing c_glib code
+- [THRIFT-71](https://issues.apache.org/jira/browse/THRIFT-71) - Debian packaging for thrift
+
+### New Feature
+- [THRIFT-1033](https://issues.apache.org/jira/browse/THRIFT-1033) - Node.js language target
+- [THRIFT-947](https://issues.apache.org/jira/browse/THRIFT-947) - Provide a helper method to determine the TProtocol used to serialize some data.
+- [THRIFT-928](https://issues.apache.org/jira/browse/THRIFT-928) - Make more statistics available in C++ servers
+- [THRIFT-922](https://issues.apache.org/jira/browse/THRIFT-922) - Templatized [de]serialization code for C++
+- [THRIFT-923](https://issues.apache.org/jira/browse/THRIFT-923) - Event-driven client and server support for C++
+- [THRIFT-925](https://issues.apache.org/jira/browse/THRIFT-925) - Provide name<->value map for enums in C++
+- [THRIFT-927](https://issues.apache.org/jira/browse/THRIFT-927) - Add option to modify the PHP include path
+- [THRIFT-377](https://issues.apache.org/jira/browse/THRIFT-377) - TFileTransport port in Java
+- [THRIFT-106](https://issues.apache.org/jira/browse/THRIFT-106) - TSSLServerSocket
+- [THRIFT-582](https://issues.apache.org/jira/browse/THRIFT-582) - C implementation of Thrift
+- [THRIFT-745](https://issues.apache.org/jira/browse/THRIFT-745) - Make it easier to instantiate servers
+
+### Sub-task
+- [THRIFT-1038](https://issues.apache.org/jira/browse/THRIFT-1038) - Generated Java code for structures containing binary fields (or collections thereof) are not serializable (in the Java sense) even though they implement java.io.Serializable
+
+### Task
+- [THRIFT-862](https://issues.apache.org/jira/browse/THRIFT-862) - Async client issues / improvements
+
+### Test
+- [THRIFT-581](https://issues.apache.org/jira/browse/THRIFT-581) - Add a testsuite for txThrift (Twisted)
+
+## Incubating Versions
+
+Thrift 0.5.0 - Incubating
+--------------------------------------------------------------------------------
+THRIFT-505 Build Make configure give a summary of the enabled components (David Reiss)
+THRIFT-506 Build Allow Thrift to be built without the C++ library (David Reiss)
+THRIFT-844 Build Build Requirements state autoconf 2.59+ is required, but 2.60+ is needed (Harlan Lieberman-Berg)
+THRIFT-850 Build Perl runtime requires Bit::Vector which may not be installed by default, but configure does not fail (Michael Lum)
+THRIFT-854 Build Provide configure option and make rules to build/install php extension (Anthony Molinaro)
+THRIFT-858 Build Have bootstrap.sh check for a suitable autoconf version before running (David Reiss)
+THRIFT-871 Build Thrift compiler for WIndows (binary distribution) (David Reiss)
+THRIFT-323 C# TJSONProtocol (Roger Meier)
+THRIFT-634 C# C# Compiler Generates Incorrect Code For Fields which begin with an uppercase letter (Jon S Akhtar)
+THRIFT-881 C# add csharp to the tutorial (Roger Meier)
+THRIFT-856 C++ Building cpp library fails on OS X with malloc and free not being declared in scope (James Clarke)
+THRIFT-865 C++ C++ compiler build depends on libfl even when flex/lex not detected (David Reiss)
+THRIFT-900 C++ Unix domain socket (Roger Meier)
+THRIFT-920 C++ C++ Test and Tutorial does not compile anymore due to the change within Enum handling (Roger Meier)
+THRIFT-567 C++ Can't immediately stop a TSimpleServer thread that is idle (Rush Manbert)
+THRIFT-756 C++ Exposing TSocket(int) constructor to public (Rajat Goel)
+THRIFT-798 C++ TNonblockingServer leaks resources when destroyed (David Reiss)
+THRIFT-812 C++, Python Demo of Thrift over ZeroMQ (David Reiss)
+THRIFT-629 Cocoa Unused Field In TSocketServer Appears To Break iPhone Build (Jon S Akhtar)
+THRIFT-838 Cocoa Generated Cocoa classes have useless @dynamic declarations (Kevin Ballard)
+THRIFT-805 Cocoa Don't generate process_XXXX methods for oneway methods (Brad Taylor)
+THRIFT-507 Compiler Remove the compiler's dependency on Boost (David Reiss)
+THRIFT-895 Compiler (General) Thrift compiler does not allow two different enumerations to have the same key name for one of the enum values (David Reiss)
+THRIFT-852 Compiler (General) Missing newline causes many compiler warnings (Anthony Molinaro)
+THRIFT-877 Compiler (General) smalltalk namespace doesn't work (Bruce Lowekamp)
+THRIFT-897 Compiler (General) Don't allow unqualified constant access to enum values (Bryan Duxbury)
+THRIFT-9 Compiler (General) Add a default namespace declaration for all languages (David Reiss)
+THRIFT-599 Erlang Don't use unnecessary processes in the Erlang transports and clients (David Reiss)
+THRIFT-646 Erlang Erlang library is missing install target (David Reiss)
+THRIFT-698 Erlang Generated module list should contain atoms, not strings (Anthony Molinaro)
+THRIFT-866 Erlang term() in spec definitions seems to not work in erlang R12 (Anthony Molinaro)
+THRIFT-886 Erlang Dialyzer warning (Anthony Molinaro)
+THRIFT-785 Erlang Framed transport server problems (Anthony Molinaro)
+THRIFT-884 HTML HTML Generator: add Key attribute to the Data Types Tables (Roger Meier)
+THRIFT-652 Haskell Generated field name for strut is not capitalized correctly (Christian Lavoie)
+THRIFT-743 Haskell compile error with GHC 6.12.1 (Christian Lavoie)
+THRIFT-901 Haskell Allow the bindings to compile without -fglasgow-exts and with -Wall -Werror (Christian Lavoie)
+THRIFT-905 Haskell Make haskell thrift bindings use automake to compile and install (Christian Lavoie)
+THRIFT-906 Haskell Improve type mappings (Christian Lavoie)
+THRIFT-914 Haskell Make haskell bindings 'easily' compilable (Christian Lavoie)
+THRIFT-918 Haskell Make haskell tests run again (Christian Lavoie)
+THRIFT-919 Haskell Update Haskell bindings README (Christian Lavoie)
+THRIFT-787 Haskell Enums are not read correctly (Christian Lavoie)
+THRIFT-250 Java ExecutorService as a constructor parameter for TServer (Ed Ceaser)
+THRIFT-693 Java Thrift compiler generated java code that throws compiler warnings about deprecated methods. (Bryan Duxbury)
+THRIFT-843 Java TNonblockingSocket connects without a timeout (Bryan Duxbury)
+THRIFT-845 Java async client does not respect timeout (Ning Liang)
+THRIFT-870 Java Java constants don't get Javadoc comments (Bryan Duxbury)
+THRIFT-873 Java Java tests fail due to Too many open files (Todd Lipcon)
+THRIFT-876 Java Add SASL support (Aaron T. Myers)
+THRIFT-879 Java Remove @Override from TUnion.clear (Dave Engberg)
+THRIFT-882 Java deep copy of binary fields does not copy ByteBuffer characteristics (arrayOffset, position) (Bryan Duxbury)
+THRIFT-888 Java async client should also have nonblocking connect (Eric Jensen)
+THRIFT-890 Java Java tutorial doesn't work (Todd Lipcon)
+THRIFT-894 Java Make default accessors for binary fields return byte[]; provide new accessors to get ByteBuffer version (Bryan Duxbury)
+THRIFT-896 Java TNonblockingSocket.isOpen() returns true even after close() (Eric Jensen)
+THRIFT-907 Java libfb303 doesn't compile in 0.4.0 (Todd Lipcon)
+THRIFT-912 Java Improvements and bug fixes to SASL implementation (Todd Lipcon)
+THRIFT-917 Java THsHaServer should not accept an ExecutorService without catching RejectedExecutionException (Ed Ceaser)
+THRIFT-931 Java Use log4j for Java tests (Todd Lipcon)
+THRIFT-880 JavaME JavaME code generator and runtime library (Dave Engberg)
+THRIFT-846 JavaScript JavaScript Test Framwork: extended Testcases (Roger Meier)
+THRIFT-885 JavaScript Url encoded strings never get decoded? How do we fix this? (T Jake Luciani)
+THRIFT-911 JavaScript (JavaScript compiler) Const structs, maps, sets, and lists generate a trailing comma (T Jake Luciani)
+THRIFT-860 OCaml copy method and reset method (Lev Walkin)
+THRIFT-682 PHP PHP extension doesn't compile on Mac OS X (Bryan Duxbury)
+THRIFT-851 PHP php extension fails to compile on centos 5.x (Todd Lipcon)
+THRIFT-840 Perl Perl protocol handler could be more robust against unrecognised types (Conrad Hughes)
+THRIFT-758 Perl incorrect deference in exception handling (Yann Kerherve)
+THRIFT-257 Python Support validation of required fields (Esteve Fernandez)
+THRIFT-335 Python Compact Protocol for Python (David Reiss)
+THRIFT-596 Python Make Python's TBufferedTransport use a configurable input buffer (David Reiss)
+THRIFT-597 Python Python THttpServer performance improvements (David Reiss)
+THRIFT-598 Python Allow Python's threading servers to use daemon threads (David Reiss)
+THRIFT-666 Python Allow the handler to override HTTP responses in THttpServer (David Reiss)
+THRIFT-673 Python Generated Python code has whitespace issues (Ian Eure)
+THRIFT-721 Python THttpClient ignores url parameters (Thomas Kho)
+THRIFT-824 Python TApplicationException.__str__() refers to class constants as globals (Peter Schuller)
+THRIFT-855 Python Include optimized compiled python objects in install (Anthony Molinaro)
+THRIFT-859 Python Allow py:twisted to be generated in different namespace than py (Bruce Lowekamp)
+THRIFT-869 Python TSocket.py on Mac (and FreeBSD) doesn't handle ECONNRESET from recv() (Steven Knight)
+THRIFT-875 Python Include python setup.cfg in dist (Anthony Molinaro)
+THRIFT-610 Ruby binary_protocol.rb segfaults [line 86] (Unassigned)
+THRIFT-899 Ruby Ruby read timeouts can sometimes be 2x what they should be (Ryan King)
+THRIFT-909 Ruby allow block argument to struct constructor (Michael Stockton)
+THRIFT-456 Test Suite Bad IP address string in test/cpp/src/main.cpp (Rush Manbert)
+
+
+Thrift 0.4.0 - Incubating
+--------------------------------------------------------------------------------
+THRIFT-650 Build Make Check fails on Centos/OSX with 0.2.0 tarball (Anthony Molinaro)
+THRIFT-770 Build Get 'make dist' to work without first compiling source code (Anthony Molinaro)
+THRIFT-160 C# Created THttpTransport for the C# library based on WebHttpRequest (Michael Greene)
+THRIFT-834 C# THttpClient resends contents of message after transport errors (Anatoly Fayngelerin)
+THRIFT-247 C++ THttpServer Transport (Unassigned)
+THRIFT-676 C++ Change C++ code generator so that generated classes can be wrapped with SWIG (Unassigned)
+THRIFT-570 Compiler Thrift compiler does not error when duplicate method names are present (Bruce Simpson)
+THRIFT-808 Compiler Segfault when constant declaration references a struct field that doesn't exist (Bryan Duxbury)
+THRIFT-646 Erlang Erlang library is missing install target (Anthony Molinaro)
+THRIFT-544 General multiple enums with the same key generate invalid code (Ben Taitelbaum)
+THRIFT-434 General ruby compiler should warn when a reserved word is used (Michael Stockton)
+THRIFT-799 General Files missing proper Apache license header (Bryan Duxbury)
+THRIFT-832 HTML HTML generator shows unspecified struct fields as 'required' (Bryan Duxbury)
+THRIFT-226 Java Collections with binary keys or values break equals() (Bryan Duxbury)
+THRIFT-484 Java Ability to use a slice of a buffer instead of a direct byte[] for binary fields (Bryan Duxbury)
+THRIFT-714 Java maxWorkerThreads parameter to THsHaServer has no effect (Bryan Duxbury)
+THRIFT-751 Java Add clear() method to TBase (Bryan Duxbury)
+THRIFT-765 Java Improved string encoding and decoding performance (Bryan Duxbury)
+THRIFT-768 Java Async client for Java (Bryan Duxbury)
+THRIFT-774 Java TDeserializer should provide a partialDeserialize method for primitive types (Piotr Kozikowski)
+THRIFT-783 Java .equals java method is broken on structs containing binary-type fields (Unassigned)
+THRIFT-804 Java CompareTo is broken for unions set to map, set, or list (Bryan Duxbury)
+THRIFT-814 Java Include a TServlet in the standard Thrift distribution (Mathias Herberts)
+THRIFT-818 Java Async client doesn't send method args (Bryan Duxbury)
+THRIFT-830 Java Switch binary field implementation from byte[] to ByteBuffer (Bryan Duxbury)
+THRIFT-831 Java FramedTransport implementation that reuses its buffers (Bryan Duxbury)
+THRIFT-833 Java build.xml in lib/java is missing a classpathref attribute for the javadoc task (Bryan Duxbury)
+THRIFT-836 Java Race condition causes CancelledKeyException in TAsyncClientManager (Bryan Duxbury)
+THRIFT-842 Java Upgrade to current version of commons-lang (2.5 instead of 2.4) and/or change dependency in ivy.xml to not be exact (Bryan Duxbury)
+THRIFT-815 JavaScript Deserialization of lists is critically broken. (T Jake Luciani)
+THRIFT-827 OCaml OCaml generator to take default values into account (Lev Walkin)
+THRIFT-647 PHP PHP library is missing install target (Anthony Molinaro)
+THRIFT-682 PHP PHP extension doesn't compile on Mac OS X (Bryan Duxbury)
+THRIFT-718 PHP Thrift PHP library includes closing tags and extraneous whitespace (Nicholas Telford)
+THRIFT-778 PHP PHP socket listening server (Nick Jones)
+THRIFT-780 PHP PHP extension sometimes causes an abort with two exceptions at the same time (David Reiss)
+THRIFT-837 PHP PHP accelerator bug for writes > 8k (Thomas Kho)
+THRIFT-782 Perl Perl code for writing containers doesn't count length of write*Begin or write*End (Conrad Hughes)
+THRIFT-395 Python Python library + compiler does not support unicode strings (Unassigned)
+THRIFT-133 Ruby 'namespace ruby' should error out, or be an alias to 'namespace rb' (Bryan Duxbury)
+THRIFT-664 Ruby Ruby extension fails to build with Ruby 1.9.1 (Rajesh Malepati)
+THRIFT-699 Ruby Excise unused "native protocol method table" stuff from thrift_native (Bryan Duxbury)
+THRIFT-767 Ruby ruby compiler does not keep comments for enum values (Bryan Duxbury)
+THRIFT-811 Ruby http_client_transport.rb: allow custom http headers (Tony Kamenick)
+THRIFT-459 Ruby Ruby installation always tries to write to /Library/Ruby/site (Matthieu Imbert)
+
+
+Thrift 0.1.0 - Incubating (not released)
+--------------------------------------------------------------------------------
+Compatibility Breaking Changes:
+ C++:
+- It's quite possible that regenerating code and rebuilding will be
+ required. Make sure your headers match your libs!
+
+ Java:
+
+ Python:
+
+ Ruby:
+- Generated files now have underscored names [THRIFT-421]
+- The library has been rearranged to be more Ruby-like [THRIFT-276]
+
+ Erlang:
+- Generated code will have to be regenerated, and the new code will
+ have to be deployed atomically with the new library code [THRIFT-136]
+
+New Features and Bug Fixes:
+ C++:
+- Support for TCompactProtocol [THRIFT-333]
+
+ Java:
+- Support for TCompactProtocol [THRIFT-110]
+
+ Python:
+- Support for Twisted [THRIFT-148]
+
+ Ruby:
+- Support for TCompactProtocol [THRIFT-332]
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9f57a66..1880b79 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,34 +17,26 @@
# under the License.
#
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.4)
-# CMake 3.1 supports C++ standards selection with CMAKE_CXX_STANDARD
-# If you need CMake 3.1+ for Ubuntu 14.04, try
-# https://launchpad.net/~george-edison55/+archive/ubuntu/cmake-3.x
-# If you need CMake 3.1+ for debian "jessie", get it from jessie-backports
-# Otherwise
-# http://cmake.org
+if(POLICY CMP0048)
+ cmake_policy(SET CMP0048 NEW) # package version behavior added in cmake 3.0
+endif()
+if(POLICY CMP0074)
+ cmake_policy(SET CMP0074 NEW) # find_package behavior added in cmake 3.12
+endif()
-project("Apache Thrift")
+# PACKAGE_VERSION is used by cpack scripts currently
+# Both thrift_VERSION and PACKAGE_VERSION should be the same for now
+set(thrift_VERSION "0.13.0")
+set(PACKAGE_VERSION ${thrift_VERSION})
+
+project("thrift" VERSION ${PACKAGE_VERSION})
+message(STATUS "Configuring ${CMAKE_PROJECT_NAME} ${thrift_VERSION}")
+
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/build/cmake")
-# TODO: add `git rev-parse --short HEAD`
-# Read the version information from the Autoconf file
-file (STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/configure.ac" CONFIGURE_AC REGEX "AC_INIT\\(.*\\)" )
-
-# The following variable is used in the version.h.in file
-string(REGEX REPLACE "AC_INIT\\(\\[.*\\], \\[([0-9]+\\.[0-9]+\\.[0-9]+(-dev)?)\\]\\)" "\\1" PACKAGE_VERSION ${CONFIGURE_AC})
-message(STATUS "Parsed Thrift package version: ${PACKAGE_VERSION}")
-
-# These are internal to CMake
-string(REGEX REPLACE "([0-9]+\\.[0-9]+\\.[0-9]+)(-dev)?" "\\1" thrift_VERSION ${PACKAGE_VERSION})
-string(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" thrift_VERSION_MAJOR ${thrift_VERSION})
-string(REGEX REPLACE "[0-9]+\\.([0-9])+\\.[0-9]+" "\\1" thrift_VERSION_MINOR ${thrift_VERSION})
-string(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" thrift_VERSION_PATCH ${thrift_VERSION})
-message(STATUS "Parsed Thrift version: ${thrift_VERSION} (${thrift_VERSION_MAJOR}.${thrift_VERSION_MINOR}.${thrift_VERSION_PATCH})")
-
# Some default settings
include(DefineCMakeDefaults)
@@ -55,16 +47,23 @@
# Based on the options set some platform specifics
include(DefinePlatformSpecifc)
+# Add CMake targets for static code analysis
+include(StaticCodeAnalysis)
+
# Generate the config.h file
include(ConfigureChecks)
-# Package it
+# Generate the ThriftConfig.cmake module
+include(GenerateConfigModule)
+
+# Packaging
include(CPackConfig)
-
+# Dependencies
+include(BoostMacros)
find_package(Threads)
-
include(CTest)
+
if(BUILD_TESTING)
message(STATUS "Building with unittests")
@@ -99,8 +98,15 @@
endif()
endif()
+if(BUILD_AS3)
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/as3)
+endif()
+
if(BUILD_C_GLIB)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/c_glib)
+ if(BUILD_TESTING)
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/test/c_glib)
+ endif()
endif()
if(BUILD_JAVA)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7a1d710..7a199f7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -13,17 +13,17 @@
on a variety of Linux and Windows configurations and run all the test suites. Follow these requirements
for a successful pull request:
- 1. All code changes require an [Apache Jira THRIFT Issue](http://issues.apache.org/jira/browse/THRIFT) ticket.
+ 1. All significant changes require an [Apache Jira THRIFT Issue](http://issues.apache.org/jira/browse/THRIFT) ticket. Trivial changes such as fixing a typo or a compiler warning do not.
1. All pull requests should contain a single commit per issue, or we will ask you to squash it.
- 1. The pull request title must begin with the Jira THRIFT ticket identifier, for example:
+ 1. The pull request title must begin with the Jira THRIFT ticket identifier if it has an associated ticket, for example:
THRIFT-9999: an example pull request title
1. Commit messages must follow this pattern for code changes (deviations will not be merged):
THRIFT-9999: [summary of fix, one line if possible]
- Client: [language(s) affected, comma separated, use lib/ directory names please]
+ Client: [language(s) affected, comma separated, for example: "cpp,erl,perl"]
Instructions:
@@ -64,11 +64,11 @@
## Contributing via Patch ##
-Some changes do not require a build, for example in documentation. For changes that are not code or build related, you can submit a patch on Jira for review. To create a patch from changes in your local directory:
+To create a patch from changes in your local directory:
git diff > ../THRIFT-NNNN.patch
-then wait for contributors or committers to review your changes, and then for a committer to apply your patch.
+then wait for contributors or committers to review your changes, and then for a committer to apply your patch. This is not the preferred way to submit changes and incurs additional overhead for committers who must then create a pull request for you.
## GitHub recipes for Pull Requests ##
diff --git a/LANGUAGES.md b/LANGUAGES.md
index acf9083..3510138 100644
--- a/LANGUAGES.md
+++ b/LANGUAGES.md
@@ -1,14 +1,38 @@
# Apache Thrift Language Support #
-Last Modified: 2018-12-17
+Guidance For: 0.13.0 |
+[0.12.0](https://github.com/apache/thrift/blob/v0.12.0/LANGUAGES.md) |
+[0.11.0](https://github.com/apache/thrift/blob/0.11.0/LANGUAGES.md)
-Guidance For: 0.12.0 or later
+Thrift supports many programming languages and has an impressive test suite that
+exercises most of the languages, protocols, and transports. Each build exercises
+a matrix of thousands of possible combinations. Each language typically has a
+minimum required version as well as support libraries - some mandatory and some
+optional. The information provided below will help you assess whether you can
+use Apache Thrift with your project. Obviously this is a complex matrix to
+maintain and may not be correct in all cases - if you spot an error please inform
+the developers using the mailing list, or better yet,
+[Edit on GitHub](https://github.com/apache/thrift/edit/master/LANGUAGES.md).
-Thrift supports many programming languages and has an impressive test suite that exercises most of the languages, protocols, and transports that represents a matrix of thousands of possible combinations. Each language typically has a minimum required version as well as support libraries - some mandatory and some optional. All of this information is provided below to help you assess whether you can use Apache Thrift with your project. Obviously this is a complex matrix to maintain and may not be correct in all cases - if you spot an error please inform the developers using the mailing list.
+Apache Thrift currently uses two build systems. The `autoconf` build system is
+the most complete and builds all supported languages, however it does not support
+Windows.. The `cmake` build system works on Linux and Windows, and has been
+designated by the project to replace `autoconf` however this transition will
+take quite some time to complete. During that transition, the cmake build will
+not support all languages.
-Apache Thrift has a choice of two build systems. The `autoconf` build system is the most complete build and is used to build all supported languages. The `cmake` build system has been designated by the project to replace `autoconf` however this transition will take quite some time to complete.
+The Language/Library Levels indicate the minimum and maximum versions that are
+used in the [continuous integration environments](build/docker/README.md)
+(Appveyor, Travis) for Apache Thrift. Other language levels may be supported
+for each language, however tested less thoroughly; check the README file inside
+each lib directory for additional details. Note: while a language may contain
+support for protocols, transports, and servers, the extent to which each is tested
+as part of the overall build process varies. The definitive integration test for
+the project is called the "cross" test which executes a test matrix with clients
+and servers communicating across languages.
-The Language/Library Levels indicate the minimum and maximum versions that are used in the [continuous integration environments](build/docker/README.md) (Appveyor, Travis) for Apache Thrift. Other language levels may be supported for each language, however tested less thoroughly; check the README file inside each lib directory for additional details. Note that while a language may contain support for protocols, transports, and servers, the extent to which each is tested as part of the overall build process varies. The definitive integration test for the project is called the "cross" test which executes a test matrix with clients and servers communicating across languages.
+Thrift's core transport (supported by all languages) is TSocket.
+Thrift's core protocol is TBinary, supported by all languages except for JavaScript.
<table style="font-size: 60%; padding: 1px;">
<thead>
@@ -18,7 +42,7 @@
<th colspan=2 align=center>Build Systems</th>
<th colspan=2 align=center>Lang/Lib Levels (Tested)</th>
<th colspan=6 align=center>Low-Level Transports</th>
-<th colspan=3 align=center>Transport Wrappers</th>
+<th colspan=4 align=center>Transport Wrappers</th>
<th colspan=4 align=center>Protocols</th>
<th colspan=5 align=center>Servers</th>
<th rowspan=2>Open Issues</th>
@@ -27,308 +51,319 @@
<!-- Build Systems ---------><th>autoconf</th><th>cmake</th>
<!-- Lang/Lib Levels -------><th>Min</th><th>Max</th>
<!-- Low-Level Transports --><th><a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Domain</a></th><th> File </th><th>Memory</th><th> Pipe </th><th>Socket</th><th> TLS </th>
-<!-- Transport Wrappers ----><th>Framed</th><th> http </th><th> zlib </th>
+<!-- Transport Wrappers ----><th>Framed</th><th>Header</th><th> http </th><th> zlib </th>
<!-- Protocols -------------><th><a href="doc/specs/thrift-binary-protocol.md">Binary</a></th><th><a href="doc/specs/thrift-compact-protocol.md">Compact</a></th><th> JSON </th><th>Multiplex</th>
<!-- Servers ---------------><th>Forking</th><th>Nonblocking</th><th>Simple</th><th>Threaded</th><th>ThreadPool</th>
</tr>
</thead>
<tbody>
<tr align=center>
-<td align=left><a href="lib/as3/README.md">ActionScript</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/as3/README.md">ActionScript</a></td>
<!-- Since -----------------><td>0.3.0</td>
-<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td colspan=2>ActionScript 3</td>
+<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<!-- Language Levels -------><td colspan=2>FLEX SDK 4.6</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313722">ActionScript</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22AS3%20-%20Compiler%22%2C%20%22AS3%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">ActionScript</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/c_glib/README.md">C (glib)</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/c_glib/README.md">C (glib)</a></td>
<!-- Since -----------------><td>0.6.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Language Levels -------><td>2.48.2</td><td>2.54.0</td>
+<!-- Language Levels -------><td>2.48.2</td><td>2.56.0</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313854">C (glib)</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22C%20glib%20-%20Compiler%22%2C%20%22C%20glib%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">C (glib)</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/cpp/README.md">C++</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/cpp/README.md">C++</a></td>
<!-- Since -----------------><td>0.2.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Language Levels -------><td colspan=2>C++98</td>
+<!-- Language Levels -------><td colspan=2>C++11</td>
<!-- Low-Level Transports --><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312313">C++</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22C%2B%2B%20-%20Compiler%22%2C%20%22C%2B%2B%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">C++</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/csharp/README.md">C#</a></td>
-<!-- Since -----------------><td>0.2.0</td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/csharp/README.md">C#</a></td>
+<!-- Since -----------------><td>0.2.0<br>Deprecated<br>use netstd</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>.NET 3.5 / mono 3.2.8.0</td><td>.NET 4.6.1 / mono 4.6.2.7</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312362">C# (.NET)</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22C%23%20-%20Compiler%22%2C%20%22C%23%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">C# (.NET)</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/cocoa/README.md">Cocoa</a></td>
-<!-- Since -----------------><td>0.2.0</td>
-<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td colspan=2>unknown</td>
-<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312398">Cocoa</a></td>
-</tr>
-<tr align=center>
-<td align=left><a href="lib/cl/README.md">Common Lisp</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/cl/README.md">Common LISP</a></td>
<!-- Since -----------------><td>0.12.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>SBCL 1.4.5</td><td>SBCL 1.4.9</td>
+<!-- Language Levels -------><td colspan=2>SBCL 1.4.x</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT-82">Common Lisp</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Common%20LISP%20-%20Compiler%22%2C%20%22Common%20LISP%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Common LISP</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/d/README.md">Dlang</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/d/README.md">Dlang</a></td>
<!-- Since -----------------><td>0.9.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>2.075.1</td><td>2.081.0</td>
+<!-- Language Levels -------><td>2.075.1</td><td>2.083.2</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12317904">D</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22D%20-%20Compiler%22%2C%20%22D%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">D</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/dart/README.md">Dart</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/dart/README.md">Dart</a></td>
<!-- Since -----------------><td>0.10.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>1.22.1</td><td>1.24.3</td>
+<!-- Language Levels -------><td>1.24.3</td><td>2.x</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12328006">Dart</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Dart%20-%20Compiler%22%2C%20%22Dart%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Dart</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/delphi/README.md">Delphi</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/delphi/README.md">Delphi</a></td>
<!-- Since -----------------><td>0.8.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>2010</td><td>unknown</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12316601">Delphi</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Delphi%20-%20Compiler%22%2C%20%22Delphi%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Delphi</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/netcore/README.md">.NET Core</a></td>
-<!-- Since -----------------><td>0.11.0</td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/netcore/README.md">.NET Core</a></td>
+<!-- Since -----------------><td>0.11.0<br>Deprecated<br>use netstd</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td colspan=2>2.1.4</td>
+<!-- Language Levels -------><td>2.1.4</td><td>2.2.101</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12331176">.NET Core</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22netcore%20-%20Compiler%22%2C%20%22netcore%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">.NET Core</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/erl/README.md">Erlang</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/netstd/README.md">.NET Standard</a></td>
+<!-- Since -----------------><td>0.13.0</td>
+<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Language Levels -------><td colspan=2>.NET 4.5+, .NET Standard 2.x</td>
+<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22netstd%20-%20Compiler%22%2C%20%22netstd%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">.NET Standard</a></td>
+</tr>
+<tr align=center>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/erl/README.md">Erlang</a></td>
<!-- Since -----------------><td>0.3.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>18.3</td><td>20.0.4</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312390">Erlang</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Erlang%20-%20Compiler%22%2C%20%22Erlang%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Erlang</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/go/README.md">Go</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/go/README.md">Go</a></td>
<!-- Since -----------------><td>0.7.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>1.7.6</td><td>1.10.3</td>
+<!-- Language Levels -------><td>1.7.6</td><td>1.11.4</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12314307">Go</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Go%20-%20Compiler%22%2C%20%22Go%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Go</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/hs/README.md">Haskell</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/hs/README.md">Haskell</a></td>
<!-- Since -----------------><td>0.5.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Language Levels -------><td>7.10.3</td><td>8.0.2</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312704">Haskell</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Haskell%20-%20Compiler%22%2C%20%22Haskell%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Haskell</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/haxe/README.md">Haxe</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/haxe/README.md">Haxe</a></td>
<!-- Since -----------------><td>0.9.3</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>3.2.1</td><td>3.4.4</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12324347">Haxe</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Haxe%20-%20Compiler%22%2C%20%22Haxe%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Haxe</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/java/README.md">Java (SE)</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/java/README.md">Java (SE)</a></td>
<!-- Since -----------------><td>0.2.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Language Levels -------><td colspan=2>1.8.0_151</td>
+<!-- Language Levels -------><td>1.8.0_151</td><td>1.8.0_191</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312314">Java SE</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Java%20-%20Compiler%22%2C%20%22Java%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Java SE</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/javame/README.md">Java (ME)</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/javame/README.md">Java (ME)</a></td>
<!-- Since -----------------><td>0.5.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td colspan=2>unknown</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313759">Java ME</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22JavaME%20-%20Compiler%22%2C%20%22JavaME%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Java ME</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/js/README.md">Javascript</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/js/README.md">Javascript</a></td>
<!-- Since -----------------><td>0.3.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td colspan=2>unknown</td>
+<!-- Language Levels -------><td>ES5</td><td>ES6</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313418">Javascript</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Javascript%20-%20Compiler%22%2C%20%22Javascript%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Javascript</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/lua/README.md">Lua</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/lua/README.md">Lua</a></td>
<!-- Since -----------------><td>0.9.2</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>5.1.5</td><td>5.2.4</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12322659">Lua</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Lua%20-%20Compiler%22%2C%20%22Lua%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Lua</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/nodejs/README.md">node.js</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/nodejs/README.md">node.js</a></td>
<!-- Since -----------------><td>0.6.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>6.x</td><td>8.11.3</td>
+<!-- Language Levels -------><td>6.x</td><td>8.x</td>
<!-- Low-Level Transports --><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12314320">node.js</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Node.js%20-%20Compiler%22%2C%20%22Node.js%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">node.js</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/nodets/README.md">node.ts</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/nodets/README.md">node.ts</a></td>
<!-- Since -----------------><td>0.12.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td>3.1.6</td><td></td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20resolution%20%3D%20Unresolved%20and%20Component%20in%20(%22TypeScript%20-%20Library%22)%20ORDER%20BY%20priority%20DESC%2C%20updated%20DESC">node.ts</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22TypeScript%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">node.ts</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/ocaml/README.md">OCaml</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/ocaml/README.md">OCaml</a></td>
<!-- Since -----------------><td>0.2.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td colspan=2>4.04.0</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313660">OCaml</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22OCaml%20-%20Compiler%22%2C%20%22OCaml%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">OCaml</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/perl/README.md">Perl</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/perl/README.md">Perl</a></td>
<!-- Since -----------------><td>0.2.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>5.22.1</td><td>5.26.0</td>
+<!-- Language Levels -------><td>5.22.1</td><td>5.26.1</td>
<!-- Low-Level Transports --><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312312">Perl</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Perl%20-%20Compiler%22%2C%20%22Perl%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Perl</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/php/README.md">PHP</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/php/README.md">PHP</a></td>
<!-- Since -----------------><td>0.2.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>7.0.22</td><td>7.1.8</td>
+<!-- Language Levels -------><td>7.0.22</td><td>7.2.10</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312431">PHP</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22PHP%20-%20Compiler%22%2C%20%22PHP%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">PHP</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/py/README.md">Python</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/py/README.md">Python</a></td>
<!-- Since -----------------><td>0.2.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Language Levels -------><td>2.7.12, 3.5.2</td><td>2.7.14, 3.6.3</td>
+<!-- Language Levels -------><td>2.7.12, 3.5.2</td><td>2.7.15rc1, 3.6.7</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312315">Python</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Python%20-%20Compiler%22%2C%20%22Python%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Python</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/rb/README.md">Ruby</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/rb/README.md">Ruby</a></td>
<!-- Since -----------------><td>0.2.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>2.3.1p112</td><td>2.3.3p222</td>
+<!-- Language Levels -------><td>2.3.1p112</td><td>2.5.1p57</td>
<!-- Low-Level Transports --><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12312316">Ruby</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Ruby%20-%20Compiler%22%2C%20%22Ruby%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Ruby</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/rs/README.md">Rust</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/rs/README.md">Rust</a></td>
<!-- Since -----------------><td>0.11.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>1.17.0</td><td>1.21.0</td>
+<!-- Language Levels -------><td>1.17.0</td><td>1.30.0</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12331420">Rust</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Rust%20-%20Compiler%22%2C%20%22Rust%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Rust</a></td>
</tr>
<tr align=center>
-<td align=left><a href="lib/st/README.md">Smalltalk</a></td>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/st/README.md">Smalltalk</a></td>
<!-- Since -----------------><td>0.2.0</td>
<!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Language Levels -------><td colspan=2>unknown</td>
<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/browse/THRIFT/component/12313861">Smalltalk</a></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Smalltalk%20-%20Compiler%22%2C%20%22Smalltalk%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Smalltalk</a></td>
+</tr>
+<tr align=center>
+<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/swift/README.md">Swift</a></td>
+<!-- Since -----------------><td>0.12.0</td>
+<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Language Levels -------><td colspan=2>4.2.1</td>
+<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
+<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Swift%20-%20Compiler%22%2C%20%22Swift%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Swift</a></td>
</tr>
</tbody>
<tfoot>
@@ -338,7 +373,7 @@
<!-- Build Systems ---------><th>autoconf</th><th>cmake</th>
<!-- Lang/Lib Levels -------><th>Min</th><th>Max</th>
<!-- Low-Level Transports --><th><a href="https://en.wikipedia.org/wiki/Unix_domain_socket">Domain</a></th></th><th> File </th><th>Memory</th><th> Pipe </th><th>Socket</th><th> TLS </th>
-<!-- Transport Wrappers ----><th>Framed</th><th> http </th><th> zlib </th>
+<!-- Transport Wrappers ----><th>Framed</th><th>Header</th><th> http </th><th> zlib </th>
<!-- Protocols -------------><th><a href="doc/specs/thrift-binary-protocol.md">Binary</a></th><th><a href="doc/specs/thrift-compact-protocol.md">Compact</a></th><th> JSON </th><th>Multiplex</th>
<!-- Servers ---------------><th>Forking</th><th>Nonblocking</th><th>Simple</th><th>Threaded</th><th>ThreadPool</th>
<th rowspan=2>Open Issues</th>
@@ -347,9 +382,10 @@
<th colspan=2 align=center>Build Systems</th>
<th colspan=2 align=center>Lang/Lib Levels (Tested)</th>
<th colspan=6 align=center>Low-Level Transports</th>
-<th colspan=3 align=center>Transport Wrappers</th>
+<th colspan=4 align=center>Transport Wrappers</th>
<th colspan=4 align=center>Protocols</th>
<th colspan=5 align=center>Servers</th>
</tr>
</tfoot>
-</table>
+</ft
+table>
diff --git a/Makefile.am b/Makefile.am
index 511452d..bacd008 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,15 +19,7 @@
ACLOCAL_AMFLAGS = -I ./aclocal
-if WITH_PLUGIN
-# To enable bootstrap, build order is lib/cpp -> compiler -> others
-SUBDIRS = lib/cpp compiler/cpp lib
-if WITH_TESTS
-SUBDIRS += lib/cpp/test
-endif
-else
SUBDIRS = compiler/cpp lib
-endif
if WITH_TESTS
SUBDIRS += test
@@ -37,8 +29,40 @@
SUBDIRS += tutorial
endif
+clean-local:
+ $(RM) -r vendor/
+
+distclean-local:
+ $(RM) -r .dub/
+ $(RM) -r autom4te.cache/
+
+CLEANFILES = \
+ composer.lock \
+ dub.selections.json
+
+DISTCLEANFILES = \
+ Makefile \
+ Makefile.in \
+ aclocal.m4 \
+ apache-thrift-test-library \
+ autoscan.log \
+ compile \
+ config.guess \
+ config.hin \
+ config.hin~ \
+ config.log \
+ config.status \
+ config.sub \
+ configure \
+ configure.scan \
+ debcomp \
+ install-sh \
+ ltmain.sh \
+ missing \
+ ylwrap
+
dist-hook:
- find $(distdir) -type f \( -iname ".DS_Store" -or -iname "._*" -or -iname ".gitignore" \) | xargs rm -rf
+ find $(distdir) -type f \( -iname ".DS_Store" -or -iname "._*" -or -iname ".gitignore" \) | xargs rm -f
find $(distdir) -type d \( -iname ".deps" -or -iname ".libs" \) | xargs rm -rf
find $(distdir) -type d \( -iname ".svn" -or -iname ".git" \) | xargs rm -rf
@@ -109,27 +133,30 @@
EXTRA_DIST = \
.clang-format \
+ .dockerignore \
.editorconfig \
.travis.yml \
.rustfmt.toml \
- .dockerignore \
+ ApacheThrift.nuspec \
appveyor.yml \
+ bootstrap.sh \
bower.json \
build \
- bootstrap.sh \
- cleanup.sh \
+ CHANGES.md \
CMakeLists.txt \
composer.json \
contrib \
CONTRIBUTING.md \
debian \
- doc \
doap.rdf \
- package.json \
- sonar-project.properties \
+ doc \
+ dub.json \
+ jitpack.yml \
LANGUAGES.md \
LICENSE \
- CHANGES \
NOTICE \
+ package.json \
+ phpcs.xml.dist \
README.md \
+ sonar-project.properties \
Thrift.podspec
diff --git a/NOTICE b/NOTICE
index 902dc8d..37824e7 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,5 @@
Apache Thrift
-Copyright 2006-2017 The Apache Software Foundation.
+Copyright (C) 2006 - 2019, The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.md b/README.md
index d09e6e1..2e8a28a 100644
--- a/README.md
+++ b/README.md
@@ -4,22 +4,27 @@
Introduction
============
-Thrift is a lightweight, language-independent software stack with an
-associated code generation mechanism for point-to-point RPC. Thrift provides
-clean abstractions for data transport, data serialization, and application
-level processing. The code generation system takes a simple definition
-language as input and generates code across programming languages that
-uses the abstracted stack to build interoperable RPC clients and servers.
+Thrift is a lightweight, language-independent software stack for
+point-to-point RPC implementation.
+Thrift provides clean abstractions and implementations for data transport,
+data serialization, and application level processing. The code generation
+system takes a simple definition language as input and generates code
+across programming languages that uses the abstracted stack to build
+interoperable RPC clients and servers.

Thrift makes it easy for programs written in different programming
languages to share data and call remote procedures. With support
-for [25 programming languages](LANGUAGES.md), chances are Thrift
+for [28 programming languages](LANGUAGES.md), chances are Thrift
supports the languages that you currently use.
Thrift is specifically designed to support non-atomic version changes
-across client and server code.
+across client and server code. This allows you to upgrade your
+server while still being able service older clients; or have newer
+clients issue requests to older servers. An excellent community-provided
+write-up about thrift and compatibility when versioning an API can be
+found in the [Thrift Missing Guide](https://diwakergupta.github.io/thrift-missing-guide/#_versioning_compatibility).
For more details on Thrift's design and implementation, see the Thrift
whitepaper included in this distribution, or at the README.md file
@@ -30,7 +35,8 @@
| Branch | Travis | Appveyor | Coverity Scan | codecov.io | Website |
| :----- | :----- | :------- | :------------ | :--------- | :------ |
-| [`master`](https://github.com/apache/thrift/tree/master) | [](https://travis-ci.org/apache/thrift) | [](https://ci.appveyor.com/project/ApacheSoftwareFoundation/thrift/history) | [](https://scan.coverity.com/projects/thrift) | | [](https://thrift.apache.org/) |
+| [`master`](https://github.com/apache/thrift/tree/master) | [](https://travis-ci.org/apache/thrift/branches) | [](https://ci.appveyor.com/project/ApacheSoftwareFoundation/thrift/history) | [](https://scan.coverity.com/projects/thrift) | | [](https://thrift.apache.org/) |
+| [`0.12.0`](https://github.com/apache/thrift/tree/0.12.0) | [](https://travis-ci.org/apache/thrift/branches) | | | | |
Releases
========
diff --git a/Thrift-swift3.podspec b/Thrift-swift3.podspec
deleted file mode 100644
index cebcdef..0000000
--- a/Thrift-swift3.podspec
+++ /dev/null
@@ -1,16 +0,0 @@
-Pod::Spec.new do |s|
- s.name = "Thrift-swift3"
- s.version = "0.12.1"
- s.summary = "Apache Thrift is a lightweight, language-independent software stack with an associated code generation mechanism for RPC."
- s.description = <<-DESC
-The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.
- DESC
- s.homepage = "http://thrift.apache.org"
- s.license = { :type => 'Apache License, Version 2.0', :url => 'https://www.apache.org/licenses/LICENSE-2.0' }
- s.author = { "Apache Thrift Developers" => "dev@thrift.apache.org" }
- s.ios.deployment_target = '9.0'
- s.osx.deployment_target = '10.10'
- s.requires_arc = true
- s.source = { :git => "https://github.com/apache/thrift.git", :tag => "v0.12.1" }
- s.source_files = "lib/swift/Sources/*.swift"
-end
diff --git a/Thrift.podspec b/Thrift.podspec
index 96ed0eb..cb1c9b2 100644
--- a/Thrift.podspec
+++ b/Thrift.podspec
@@ -1,18 +1,16 @@
Pod::Spec.new do |s|
- s.name = "Thrift"
- s.version = "0.12.1"
+ s.name = "Thrift-swift3"
+ s.version = "0.13.0"
s.summary = "Apache Thrift is a lightweight, language-independent software stack with an associated code generation mechanism for RPC."
s.description = <<-DESC
-The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.
+The Apache Thrift scalable cross-language software framework for networked services development combines a software stack with a code generation engine to build services that work efficiently and seamlessly between many programming languages.
DESC
s.homepage = "http://thrift.apache.org"
s.license = { :type => 'Apache License, Version 2.0', :url => 'https://www.apache.org/licenses/LICENSE-2.0' }
s.author = { "Apache Thrift Developers" => "dev@thrift.apache.org" }
+ s.ios.deployment_target = '9.0'
+ s.osx.deployment_target = '10.10'
s.requires_arc = true
- s.ios.deployment_target = '7.0'
- s.osx.deployment_target = '10.8'
- s.ios.framework = 'CFNetwork'
- s.osx.framework = 'CoreServices'
- s.source = { :git => "https://github.com/apache/thrift.git", :tag => "v0.12.1" }
- s.source_files = 'lib/cocoa/src/**/*.{h,m,swift}'
+ s.source = { :git => "https://github.com/apache/thrift.git", :tag => "v0.13.0" }
+ s.source_files = "lib/swift/Sources/*.swift"
end
diff --git a/appveyor.yml b/appveyor.yml
index 2c3bd9b..ef729eb 100755
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -19,16 +19,19 @@
# build Apache Thrift on AppVeyor - https://ci.appveyor.com
-version: '0.12.1.{build}'
+version: '0.13.0.{build}'
shallow_clone: true
+branches:
+ only:
+ - master
+ - /^(release/)?\d+\.\d+\.\d+$/
+
os:
- Visual Studio 2017
matrix:
- allow_failures:
- - PROFILE: CYGWIN
fast_finish: true
environment:
@@ -36,39 +39,36 @@
- PROFILE: MSVC2017
PLATFORM: x64
CONFIGURATION: Release
- BOOST_VERSION: 1.65.1
+ BUILD_SHARED_LIBS: ON
+ BOOST_VERSION: 1.67.0
LIBEVENT_VERSION: 2.1.8
PYTHON_VERSION: 3.6
QT_VERSION: 5.10
ZLIB_VERSION: 1.2.11
- DISABLED_TESTS: StressTestNonBlocking
+ DISABLED_TESTS: (StressTestNonBlocking)
- - PROFILE: MSVC2013
+ - PROFILE: MSVC2015
PLATFORM: x86
- CONFIGURATION: Release
- BOOST_VERSION: 1.58.0
+ CONFIGURATION: Debug
+ BUILD_SHARED_LIBS: OFF
+ BOOST_VERSION: 1.62.0
LIBEVENT_VERSION: 2.0.22
PYTHON_VERSION: 3.5
QT_VERSION: 5.8
ZLIB_VERSION: 1.2.8
- DISABLED_TESTS: StressTestNonBlocking
+ DISABLED_TESTS: (StressTestNonBlocking)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- PROFILE: MINGW
PLATFORM: x64
CONFIGURATION: RelWithDebInfo
- DISABLED_TESTS: StressTestNonBlocking
+ DISABLED_TESTS: (StalenessCheckTest|StressTestNonBlocking)
- PROFILE: CYGWIN
- PLATFORM: x86
+ PLATFORM: x64
CONFIGURATION: RelWithDebInfo
DISABLED_TESTS: (ZlibTest|OpenSSLManualInitTest|TNonblockingServerTest|StressTestNonBlocking)
-# - PROFILE: CYGWIN
-# PLATFORM: x64
-# CONFIGURATION: RelWithDebInfo
-# DISABLED_TESTS: (ZlibTest|OpenSSLManualInitTest|TNonblockingServerTest|StressTestNonBlocking)
-
install:
- cd %APPVEYOR_BUILD_FOLDER%
- call build\appveyor\%PROFILE:~0,4%-appveyor-install.bat
@@ -102,8 +102,8 @@
#
# enables RDP at the end of the build job so you can login and re-run
# commands to see why something failed...
-#on_finish:
-# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
+# on_finish:
+# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
#
# also need:
# environment:
diff --git a/bootstrap.sh b/bootstrap.sh
index 2452eea..1989437 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -19,7 +19,10 @@
# under the License.
#
-./cleanup.sh
+echo -n "make distclean... "
+make -k distclean >/dev/null 2>&1
+echo "ok"
+
if test -d lib/php/src/ext/thrift_protocol ; then
if phpize -v >/dev/null 2>/dev/null ; then
(cd lib/php/src/ext/thrift_protocol && phpize)
diff --git a/bower.json b/bower.json
index c19b2a5..c602af1 100644
--- a/bower.json
+++ b/bower.json
@@ -1,7 +1,7 @@
{
"name": "thrift",
- "version": "0.12.1",
- "homepage": "https://git-wip-us.apache.org/repos/asf/thrift.git",
+ "version": "0.13.0",
+ "homepage": "https://github.com/apache/thrift.git",
"authors": [
"Apache Thrift <dev@thrift.apache.org>"
],
@@ -11,6 +11,5 @@
"thrift"
],
"license": "Apache v2",
- "ignore": [
- ]
+ "ignore": []
}
diff --git a/build/appveyor/CYGW-appveyor-build.bat b/build/appveyor/CYGW-appveyor-build.bat
index c226222..7f33287 100644
--- a/build/appveyor/CYGW-appveyor-build.bat
+++ b/build/appveyor/CYGW-appveyor-build.bat
@@ -23,13 +23,12 @@
-G'%GENERATOR%' ^
-DCMAKE_BUILD_TYPE=%CONFIGURATION% ^
-DCMAKE_INSTALL_PREFIX=%INSTDIR% ^
- -DCMAKE_CXX_EXTENSIONS=ON ^
-DCMAKE_CXX_FLAGS="-D_GNU_SOURCE" ^
- -DCMAKE_CXX_STANDARD=11 ^
- -DWITH_PYTHON=OFF ^
- -DWITH_SHARED_LIB=OFF ^
- -DWITH_STATIC_LIB=ON ^
- -DWITH_STDTHREADS=ON
+ -DWITH_JAVA=OFF ^
+ -DWITH_PYTHON=OFF
+
+:: -DCMAKE_CXX_EXTENSIONS=ON ^
+:: -DCMAKE_CXX_STANDARD=11 ^
@ECHO ON
%BASH% -lc "mkdir -p %BUILDDIR% && cd %BUILDDIR% && cmake.exe %SRCDIR% %CMAKEARGS% && cmake --build . --config %CONFIGURATION% --target install" || EXIT /B
diff --git a/build/appveyor/CYGW-appveyor-install.bat b/build/appveyor/CYGW-appveyor-install.bat
index 77db7d4..72712b2 100644
--- a/build/appveyor/CYGW-appveyor-install.bat
+++ b/build/appveyor/CYGW-appveyor-install.bat
@@ -26,9 +26,25 @@
CALL cl_showenv.bat || EXIT /B
::
+:: Upgrades cygwin to the latest, if you want...
+::
+:: appveyor DownloadFile "https://cygwin.com/setup-x86_64.exe"
+:: setup-x86_64.exe --quiet-mode --wait --upgrade-also --packages="gcc-g++"
+
+::
:: Install apt-cyg for package management
::
%BASH% -lc "wget rawgit.com/transcode-open/apt-cyg/master/apt-cyg && install apt-cyg /bin && rm -f apt-cyg" || EXIT /B
%BASH% -lc "apt-cyg update" || EXIT /B
-%BASH% -lc "apt-cyg install bison cmake flex gcc-g++ libboost-devel libevent-devel make openssl-devel zlib-devel"
+%BASH% -lc "apt-cyg install bison cmake flex gcc-g++ libboost-devel libevent-devel make openssl-devel xz zlib-devel"
+
+::
+:: We need a newer version of cmake, the one cygwin provides is too old
+:: to recognize the version of boost. Luckily there is a pre-release
+:: one available, however cygwin's own setup program has no command line
+:: option to allow access to test packages!
+::
+
+%BASH% -lc "apt-cyg remove cmake"
+%BASH% -lc "cd / && wget http://mirror.clarkson.edu/cygwin/x86_64/release/cmake/cmake-3.13.1-1.tar.xz && tar xJf cmake-3.13.1-1.tar.xz && hash -r && cmake --version"
diff --git a/build/appveyor/MING-appveyor-build.bat b/build/appveyor/MING-appveyor-build.bat
index b37a95a..eec65f8 100644
--- a/build/appveyor/MING-appveyor-build.bat
+++ b/build/appveyor/MING-appveyor-build.bat
@@ -27,9 +27,7 @@
-DCMAKE_C_COMPILER=/mingw%NORM_PLATFORM%/bin/gcc.exe ^
-DCMAKE_CXX_COMPILER=/mingw%NORM_PLATFORM%/bin/g++.exe ^
-DOPENSSL_ROOT_DIR=/mingw%NORM_PLATFORM% ^
- -DWITH_PYTHON=OFF ^
- -DWITH_SHARED_LIB=OFF ^
- -DWITH_STATIC_LIB=ON
+ -DWITH_PYTHON=OFF
@ECHO ON
%BASH% -lc "mkdir -p %BUILDDIR% && cd %BUILDDIR% && cmake.exe %SRCDIR% %CMAKEARGS% && cmake --build . --config %CONFIGURATION% --target install" || EXIT /B
diff --git a/build/appveyor/MSVC-appveyor-build.bat b/build/appveyor/MSVC-appveyor-build.bat
index a4b92a2..3d2bbee 100644
--- a/build/appveyor/MSVC-appveyor-build.bat
+++ b/build/appveyor/MSVC-appveyor-build.bat
@@ -21,25 +21,37 @@
MKDIR "%BUILDDIR%" || EXIT /B
CD "%BUILDDIR%" || EXIT /B
+:: When libraries cannot be found, things might have been updated
+:: so uncomment this and submit a pull request to see what's there
+:: now...
+:: DIR C:\Libraries
+:: DIR C:\Libraries\boost_1_69_0\lib*
+:: DIR C:\Libraries\boost_1_68_0\lib*
+:: DIR C:\Libraries\boost_1_67_0\lib*
+:: DIR C:\Libraries\boost_1_66_0\lib*
+:: DIR C:\Libraries\boost_1_65_0\lib*
+:: DIR C:\Libraries\boost_1_64_0\lib*
+:: DIR C:\Libraries\boost_1_63_0\lib*
+:: DIR C:\Libraries\boost_1_62_0\lib*
+:: DIR C:\Libraries\boost_1_61_0\lib*
+:: DIR C:\Libraries\boost_1_60_0\lib*
+
@ECHO ON
cmake "%SRCDIR%" ^
-G"%GENERATOR%" ^
-DBISON_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison3\tools\win_bison.exe ^
-DBOOST_ROOT="%BOOST_ROOT%" ^
-DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%" ^
+ -DBUILD_SHARED_LIBS="%BUILD_SHARED_LIBS%" ^
-DCMAKE_BUILD_TYPE="%CONFIGURATION%" ^
-DCMAKE_INSTALL_PREFIX="%INSTDIR%" ^
-DFLEX_EXECUTABLE=C:\ProgramData\chocolatey\lib\winflexbison3\tools\win_flex.exe ^
- -DINTTYPES_ROOT="%WIN3P%\msinttypes" ^
-DLIBEVENT_ROOT="%WIN3P%\libevent-%LIBEVENT_VERSION%-stable" ^
-DOPENSSL_ROOT_DIR="%OPENSSL_ROOT%" ^
-DOPENSSL_USE_STATIC_LIBS=OFF ^
-DZLIB_LIBRARY="%WIN3P%\zlib-inst\lib\zlib%ZLIB_LIB_SUFFIX%.lib" ^
-DZLIB_ROOT="%WIN3P%\zlib-inst" ^
- -DWITH_PYTHON=%WITH_PYTHON% ^
- -DWITH_%THREADMODEL%THREADS=ON ^
- -DWITH_SHARED_LIB=OFF ^
- -DWITH_STATIC_LIB=ON || EXIT /B
+ -DWITH_PYTHON=%WITH_PYTHON% || EXIT /B
@ECHO OFF
cmake --build . ^
diff --git a/build/appveyor/MSVC-appveyor-install.bat b/build/appveyor/MSVC-appveyor-install.bat
index f973d29..bc4655a 100644
--- a/build/appveyor/MSVC-appveyor-install.bat
+++ b/build/appveyor/MSVC-appveyor-install.bat
@@ -57,3 +57,10 @@
twisted || EXIT /B
cinst -y ghc || EXIT /B
+
+:: Adobe Flex SDK 4.6 for ActionScript
+MKDIR "C:\Adobe\Flex\SDK\4.6" || EXIT /B
+appveyor DownloadFile http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip -FileName C:\Adobe\Flex\SDK\4.6\SDK.zip || EXIT /B
+CD "C:\Adobe\Flex\SDK\4.6" || EXIT /B
+7z x SDK.zip || EXIT /B
+SETX FLEX_HOME "C:\Adobe\Flex\SDK\4.6"
diff --git a/build/appveyor/cl_setenv.bat b/build/appveyor/cl_setenv.bat
index 62856cb..98931a6 100644
--- a/build/appveyor/cl_setenv.bat
+++ b/build/appveyor/cl_setenv.bat
@@ -14,9 +14,7 @@
@ECHO OFF
- IF "%PROFILE%" == "MSVC2010" (
- CALL "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" %PLATFORM%
-) ELSE IF "%PROFILE%" == "MSVC2012" (
+IF "%PROFILE%" == "MSVC2012" (
CALL "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" %PLATFORM%
) ELSE IF "%PROFILE%" == "MSVC2013" (
CALL "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" %PLATFORM%
@@ -54,13 +52,6 @@
SET OPENSSL_ROOT=C:\OpenSSL-Win%NORM_PLATFORM%
SET WIN3P=%APPVEYOR_BUILD_FOLDER%\thirdparty
- :: MSVC2010 doesn't "do" std::thread
- IF "%COMPILER%" == "vc100" (
- SET THREADMODEL=BOOST
- ) ELSE (
- SET THREADMODEL=STD
- )
-
IF "%PYTHON_VERSION%" == "" (
SET WITH_PYTHON=OFF
) ELSE (
@@ -114,15 +105,18 @@
GOTO :EOF
:SETUPNEWERMSVC
- FOR /F "USEBACKQ TOKENS=*" %%i IN (`call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -version "[15.0,16.0)" -property installationPath`) DO (
- IF "%MSVCROOT%" == "" (SET MSVCROOT=%%i)
+ :: If VsDevCmd.bat has already executed, as is the case in the
+ :: msvc2017 docker container, skip this...
+ IF NOT DEFINED VSCMD_VER (
+ FOR /F "USEBACKQ TOKENS=*" %%i IN (`call "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -version "[15.0,16.0)" -property installationPath`) DO (
+ IF "%MSVCROOT%" == "" (SET MSVCROOT=%%i)
+ )
+ SET MSVCPLAT=x86
+ IF "%PLATFORM%" == "x64" (SET MSVCPLAT=amd64)
+
+ SET CURRENTDIR=%CD%
+ CALL "!MSVCROOT!\Common7\Tools\VsDevCmd.bat" -arch=!MSVCPLAT! || EXIT /B
+ CD %CURRENTDIR%
+ EXIT /B
)
- SET MSVCPLAT=x86
- IF "%PLATFORM%" == "x64" (SET MSVCPLAT=amd64)
-
- SET CURRENTDIR=%CD%
- CALL "!MSVCROOT!\Common7\Tools\VsDevCmd.bat" -arch=!MSVCPLAT! || EXIT /B
- CD %CURRENTDIR%
- EXIT /B
-
:EOF
diff --git a/build/cmake/BoostMacros.cmake b/build/cmake/BoostMacros.cmake
new file mode 100644
index 0000000..cc50b53
--- /dev/null
+++ b/build/cmake/BoostMacros.cmake
@@ -0,0 +1,49 @@
+#
+# 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.
+#
+
+set(BOOST_MINREV 1.56)
+
+# we are not ready for the new style link targets introduced in
+# boost 1.70.0 and cmake 3.14.2 which showed up on appveyor in
+# mingw builds
+set(Boost_NO_BOOST_CMAKE ON)
+
+macro(REQUIRE_BOOST_HEADERS)
+ find_package(Boost ${BOOST_MINREV} QUIET REQUIRED)
+ if (NOT Boost_FOUND)
+ string(CONCAT fatal_message
+ "Boost ${BOOST_MINREV} or later is required to build sources in ${CMAKE_CURRENT_SOURCE_DIR}")
+ message(FATAL_ERROR, ${fatal_message})
+ endif()
+ if (DEFINED Boost_INCLUDE_DIRS)
+ # pre-boost 1.70.0 aware cmake, otherwise it is using targets
+ include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
+ endif()
+endmacro()
+
+macro(REQUIRE_BOOST_LIBRARIES libs)
+ message(STATUS "Locating boost libraries required by sources in ${CMAKE_CURRENT_SOURCE_DIR}")
+ find_package(Boost ${BOOST_MINREV} REQUIRED COMPONENTS ${${libs}})
+ if (NOT Boost_FOUND)
+ string(CONCAT fatal_message
+ "Boost ${BOOST_MINREV} or later is required to build sources in ${CMAKE_CURRENT_SOURCE_DIR}, "
+ "or use -DBUILD_TESTING=OFF")
+ message(FATAL_ERROR, ${fatal_message})
+ endif()
+endmacro()
diff --git a/build/cmake/BuildType.cmake b/build/cmake/BuildType.cmake
new file mode 100644
index 0000000..b3bf353
--- /dev/null
+++ b/build/cmake/BuildType.cmake
@@ -0,0 +1,36 @@
+#
+# 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.
+#
+
+# originally from:
+# https://raw.githubusercontent.com/OpenChemistry/tomviz/master/cmake/BuildType.cmake
+
+# Set a default build type if none was specified
+set(default_build_type "RelWithDebInfo")
+if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
+ set(default_build_type "Debug")
+endif()
+
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
+ set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
+ STRING "Choose the type of build." FORCE)
+ # Set the possible values of build type for cmake-gui
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
+ "MinSizeRel" "RelWithDebInfo")
+endif()
diff --git a/build/cmake/DefineCMakeDefaults.cmake b/build/cmake/DefineCMakeDefaults.cmake
index d9f3d72..2b0cdbb 100644
--- a/build/cmake/DefineCMakeDefaults.cmake
+++ b/build/cmake/DefineCMakeDefaults.cmake
@@ -34,21 +34,12 @@
# since cmake 2.4.0
set(CMAKE_COLOR_MAKEFILE ON)
-# Define the generic version of the libraries here
-set(GENERIC_LIB_VERSION "0.12.1")
-set(GENERIC_LIB_SOVERSION "0")
-
-# Set the default build type to release with debug info
-if (NOT CMAKE_BUILD_TYPE)
- set(CMAKE_BUILD_TYPE RelWithDebInfo
- CACHE STRING
- "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
- )
-endif (NOT CMAKE_BUILD_TYPE)
-
# Create the compile command database for clang by default
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+# Set the CMAKE_BUILD_TYPE if it is not already defined
+include(BuildType)
+
# Put the libraries and binaries that get built into directories at the
# top of the build tree rather than in hard-to-find leaf
# directories. This simplifies manual testing and the use of the build
@@ -73,21 +64,29 @@
# C++ Language Level Defaults - this depends on the compiler capabilities
#
if (NOT DEFINED CMAKE_CXX_STANDARD)
- if (MSVC AND MSVC_VERSION LESS 1800)
- # MSVC 2012 and earlier don't support template aliases so you have to use C++98
- set(CMAKE_CXX_STANDARD 98)
- message(STATUS "Setting C++98 as the default language level (for an older MSVC compiler).")
- else()
- set(CMAKE_CXX_STANDARD 11) # C++11
- message(STATUS "Setting C++11 as the default language level.")
- endif()
+ set(CMAKE_CXX_STANDARD 11) # C++11
+ message(STATUS "Setting C++11 as the default language level.")
message(STATUS "To specify a different C++ language level, set CMAKE_CXX_STANDARD")
endif()
-if (NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED)
- set(CMAKE_CXX_STANDARD_REQUIRED OFF) # can degrade to C++98 if compiler does not support C++11
+if (CMAKE_CXX_STANDARD EQUAL 98)
+ message(FATAL_ERROR "only C++11 or above C++ standard is supported")
+elseif (CMAKE_CXX_STANDARD EQUAL 11)
+ # should not fallback to C++98
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
if (NOT DEFINED CMAKE_CXX_EXTENSIONS)
set(CMAKE_CXX_EXTENSIONS OFF) # use standards compliant language level for portability
endif()
+
+if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ include(CheckCXXCompilerFlag)
+ set(CMAKE_REQUIRED_QUIET ON)
+ check_cxx_compiler_flag("/Zc:__cplusplus" res_var)
+ if (res_var)
+ # Make MSVC reporting correct value for __cplusplus
+ # See https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/
+ add_compile_options("/Zc:__cplusplus")
+ endif()
+endif()
diff --git a/build/cmake/DefineInstallationPaths.cmake b/build/cmake/DefineInstallationPaths.cmake
index 122f0f6..0c824cc 100644
--- a/build/cmake/DefineInstallationPaths.cmake
+++ b/build/cmake/DefineInstallationPaths.cmake
@@ -22,5 +22,11 @@
set(BIN_INSTALL_DIR "bin" CACHE PATH "The binary install dir (default: bin)")
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The library install dir (default: lib${LIB_SUFFIX})")
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "The library install dir (default: include)")
-set(CMAKE_INSTALL_DIR "cmake" CACHE PATH "The subdirectory to install cmake config files (default: cmake)")
+set(CMAKE_INSTALL_DIR "lib/cmake" CACHE PATH "The subdirectory to install cmake config files (default: cmake)")
+set(PKGCONFIG_INSTALL_DIR "lib/pkgconfig" CACHE PATH "The subdirectory to install pkgconfig config files (default: lib/pkgconfig)")
set(DOC_INSTALL_DIR "share/doc" CACHE PATH "The subdirectory to install documentation files (default: share/doc)")
+set(prefix "${CMAKE_INSTALL_PREFIX}")
+set(exec_prefix "${CMAKE_INSTALL_PREFIX}/bin")
+set(libdir "${CMAKE_INSTALL_PREFIX}/lib")
+set(includedir "${CMAKE_INSTALL_PREFIX}/include")
+set(cmakedir "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DIR}")
diff --git a/build/cmake/DefineOptions.cmake b/build/cmake/DefineOptions.cmake
index f419229..778be8d 100644
--- a/build/cmake/DefineOptions.cmake
+++ b/build/cmake/DefineOptions.cmake
@@ -29,7 +29,6 @@
set(HAVE_COMPILER ON)
endif()
CMAKE_DEPENDENT_OPTION(BUILD_TESTING "Build with unit tests" ON "HAVE_COMPILER" OFF)
-CMAKE_DEPENDENT_OPTION(BUILD_EXAMPLES "Build examples" ON "HAVE_COMPILER" OFF)
CMAKE_DEPENDENT_OPTION(BUILD_TUTORIALS "Build Thrift tutorials" ON "HAVE_COMPILER" OFF)
option(BUILD_LIBRARIES "Build Thrift libraries" ON)
@@ -40,27 +39,23 @@
# and enables the library if all are found. This means the default is to build as
# much as possible but leaving out libraries if their dependencies are not met.
-option(WITH_BOOST_FUNCTIONAL "Use boost/tr1/functional.hpp even under C++11 or later" OFF)
-if (WITH_BOOST_FUNCTIONAL)
- add_definitions(-DFORCE_BOOST_FUNCTIONAL)
-endif()
-
-option(WITH_BOOST_SMART_PTR "Use boost/smart_ptr.hpp even under C++11 or later" OFF)
-if (WITH_BOOST_SMART_PTR)
- add_definitions(-DFORCE_BOOST_SMART_PTR)
-endif()
-
-option(WITH_BOOST_STATIC "Build with Boost static link library" OFF)
-set(Boost_USE_STATIC_LIBS ${WITH_BOOST_STATIC})
-if (NOT WITH_BOOST_STATIC)
+if (NOT Boost_USE_STATIC_LIBS)
add_definitions(-DBOOST_ALL_DYN_LINK)
add_definitions(-DBOOST_TEST_DYN_LINK)
endif()
+# as3
+option(WITH_AS3 "Build ActionScript 3 Thrift Library" ON)
+if (WITH_AS3)
+ set(POSSIBLE_PATHS "${FLEX_HOME}/bin" "$ENV{FLEX_HOME}/bin")
+ find_program(HAVE_COMPC NAMES compc HINTS ${POSSIBLE_PATHS})
+endif ()
+CMAKE_DEPENDENT_OPTION(BUILD_AS3 "Build as3 library" ON
+ "BUILD_LIBRARIES;WITH_AS3;HAVE_COMPC" OFF)
+
# C++
option(WITH_CPP "Build C++ Thrift library" ON)
if(WITH_CPP)
- find_package(Boost 1.53 QUIET)
# NOTE: Currently the following options are C++ specific,
# but in future other libraries might reuse them.
# So they are not dependent on WITH_CPP but setting them without WITH_CPP currently
@@ -75,27 +70,15 @@
find_package(Libevent QUIET)
CMAKE_DEPENDENT_OPTION(WITH_LIBEVENT "Build with libevent support" ON
"Libevent_FOUND" OFF)
- find_package(Qt4 QUIET COMPONENTS QtCore QtNetwork)
- CMAKE_DEPENDENT_OPTION(WITH_QT4 "Build with Qt4 support" ON
- "QT4_FOUND" OFF)
find_package(Qt5 QUIET COMPONENTS Core Network)
CMAKE_DEPENDENT_OPTION(WITH_QT5 "Build with Qt5 support" ON
"Qt5_FOUND" OFF)
- if(${WITH_QT4} AND ${WITH_QT5} AND ${CMAKE_MAJOR_VERSION} LESS 3)
- # cmake < 3.0.0 causes conflict when building both Qt4 and Qt5
- set(WITH_QT4 OFF)
- endif()
find_package(OpenSSL QUIET)
CMAKE_DEPENDENT_OPTION(WITH_OPENSSL "Build with OpenSSL support" ON
"OPENSSL_FOUND" OFF)
- option(WITH_STDTHREADS "Build with C++ std::thread support" OFF)
- CMAKE_DEPENDENT_OPTION(WITH_BOOSTTHREADS "Build with Boost threads support" OFF
- "NOT WITH_STDTHREADS;Boost_FOUND" OFF)
endif()
CMAKE_DEPENDENT_OPTION(BUILD_CPP "Build C++ library" ON
- "BUILD_LIBRARIES;WITH_CPP;Boost_FOUND" OFF)
-CMAKE_DEPENDENT_OPTION(WITH_PLUGIN "Build compiler plugin support" OFF
- "BUILD_COMPILER;BUILD_CPP" OFF)
+ "BUILD_LIBRARIES;WITH_CPP" OFF)
# C GLib
option(WITH_C_GLIB "Build C (GLib) Thrift library" ON)
@@ -105,21 +88,6 @@
CMAKE_DEPENDENT_OPTION(BUILD_C_GLIB "Build C (GLib) library" ON
"BUILD_LIBRARIES;WITH_C_GLIB;GLIB_FOUND" OFF)
-if(BUILD_CPP)
- set(boost_components)
- if(WITH_BOOSTTHREADS OR BUILD_TESTING)
- list(APPEND boost_components system thread)
- endif()
- if(BUILD_TESTING)
- list(APPEND boost_components unit_test_framework filesystem chrono program_options)
- endif()
- if(boost_components)
- find_package(Boost 1.53 REQUIRED COMPONENTS ${boost_components})
- endif()
-elseif(BUILD_C_GLIB AND BUILD_TESTING)
- find_package(Boost 1.53 REQUIRED)
-endif()
-
# Java
option(WITH_JAVA "Build Java Thrift library" ON)
if(ANDROID)
@@ -138,7 +106,7 @@
find_package(PythonInterp QUIET) # for Python executable
find_package(PythonLibs QUIET) # for Python.h
CMAKE_DEPENDENT_OPTION(BUILD_PYTHON "Build Python library" ON
- "BUILD_LIBRARIES;WITH_PYTHON;PYTHONLIBS_FOUND" OFF)
+ "BUILD_LIBRARIES;WITH_PYTHON;PYTHONINTERP_FOUND;PYTHONLIBS_FOUND" OFF)
# Haskell
option(WITH_HASKELL "Build Haskell Thrift library" ON)
@@ -148,22 +116,29 @@
"BUILD_LIBRARIES;WITH_HASKELL;GHC_FOUND;CABAL_FOUND" OFF)
# Common library options
-option(WITH_SHARED_LIB "Build shared libraries" ON)
-option(WITH_STATIC_LIB "Build static libraries" ON)
-if (NOT WITH_SHARED_LIB AND NOT WITH_STATIC_LIB)
- message(FATAL_ERROR "Cannot build with both shared and static outputs disabled!")
-endif()
+# https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html
+# Default on Windows is static, shared mode library support needs work...
+CMAKE_DEPENDENT_OPTION(BUILD_SHARED_LIBS "Build shared libraries" OFF "WIN32" ON)
-#NOTE: C++ compiler options are defined in the lib/cpp/CMakeLists.txt
+if (WITH_SHARED_LIB)
+ message(WARNING "WITH_SHARED_LIB is deprecated; use -DBUILD_SHARED_LIBS=ON instead")
+ set(BUILD_SHARED_LIBS ON)
+elseif (WITH_STATIC_LIB)
+ if (WITH_SHARED_LIB)
+ message(FATAL_ERROR "Cannot build shared and static together; set BUILD_SHARED_LIBS instead.")
+ endif ()
+ message(WARNING "WITH_STATIC_LIB is deprecated; use -DBUILD_SHARED_LIBS=OFF instead")
+ set(BUILD_SHARED_LIBS OFF)
+endif ()
# Visual Studio only options
if(MSVC)
-option(WITH_MT "Build using MT instead of MD (MSVC only)" OFF)
+ option(WITH_MT "Build using MT instead of MD (MSVC only)" OFF)
endif(MSVC)
macro(MESSAGE_DEP flag summary)
if(NOT ${flag})
- message(STATUS " - ${summary}")
+ message(STATUS " - ${summary}")
endif()
endmacro(MESSAGE_DEP flag summary)
@@ -171,22 +146,34 @@
message(STATUS "----------------------------------------------------------")
message(STATUS "Thrift version: ${thrift_VERSION} (${thrift_VERSION_MAJOR}.${thrift_VERSION_MINOR}.${thrift_VERSION_PATCH})")
message(STATUS "Thrift package version: ${PACKAGE_VERSION}")
-message(STATUS "Build configuration Summary")
-message(STATUS " Build Thrift compiler: ${BUILD_COMPILER}")
-message(STATUS " Build compiler plugin support: ${WITH_PLUGIN}")
-message(STATUS " Build with unit tests: ${BUILD_TESTING}")
+message(STATUS)
+message(STATUS "Build configuration summary")
+message(STATUS " Build compiler: ${BUILD_COMPILER}")
+message(STATUS " Build libraries: ${BUILD_LIBRARIES}")
+message(STATUS " Build tests: ${BUILD_TESTING}")
MESSAGE_DEP(HAVE_COMPILER "Disabled because BUILD_THRIFT=OFF and no valid THRIFT_COMPILER is given")
-message(STATUS " Build examples: ${BUILD_EXAMPLES}")
-MESSAGE_DEP(HAVE_COMPILER "Disabled because BUILD_THRIFT=OFF and no valid THRIFT_COMPILER is given")
-message(STATUS " Build Thrift libraries: ${BUILD_LIBRARIES}")
-message(STATUS " Language libraries:")
+message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
+message(STATUS)
+message(STATUS "Language libraries:")
+message(STATUS)
+message(STATUS " Build as3 library: ${BUILD_AS3}")
+MESSAGE_DEP(WITH_AS3 "Disabled by WITH_AS3=OFF")
+MESSAGE_DEP(HAVE_COMPC "Adobe Flex compc was not found - did you set env var FLEX_HOME?")
+message(STATUS)
message(STATUS " Build C++ library: ${BUILD_CPP}")
MESSAGE_DEP(WITH_CPP "Disabled by WITH_CPP=OFF")
-MESSAGE_DEP(Boost_FOUND "Boost headers missing")
-message(STATUS " C++ Language Level: ${CXX_LANGUAGE_LEVEL}")
+if (BUILD_CPP)
+ message(STATUS " C++ Language Level: ${CXX_LANGUAGE_LEVEL}")
+ message(STATUS " Build shared libraries: ${BUILD_SHARED_LIBS}")
+ message(STATUS " Build with libevent support: ${WITH_LIBEVENT}")
+ message(STATUS " Build with Qt5 support: ${WITH_QT5}")
+ message(STATUS " Build with ZLIB support: ${WITH_ZLIB}")
+endif ()
+message(STATUS)
message(STATUS " Build C (GLib) library: ${BUILD_C_GLIB}")
MESSAGE_DEP(WITH_C_GLIB "Disabled by WITH_C_GLIB=OFF")
MESSAGE_DEP(GLIB_FOUND "GLib missing")
+message(STATUS)
message(STATUS " Build Java library: ${BUILD_JAVA}")
MESSAGE_DEP(WITH_JAVA "Disabled by WITH_JAVA=OFF")
if(ANDROID)
@@ -195,25 +182,15 @@
MESSAGE_DEP(JAVA_FOUND "Java Runtime missing")
MESSAGE_DEP(GRADLEW_FOUND "Gradle Wrapper missing")
endif()
+message(STATUS)
message(STATUS " Build Python library: ${BUILD_PYTHON}")
MESSAGE_DEP(WITH_PYTHON "Disabled by WITH_PYTHON=OFF")
MESSAGE_DEP(PYTHONLIBS_FOUND "Python libraries missing")
+message(STATUS)
message(STATUS " Build Haskell library: ${BUILD_HASKELL}")
MESSAGE_DEP(WITH_HASKELL "Disabled by WITH_HASKELL=OFF")
MESSAGE_DEP(GHC_FOUND "GHC missing")
MESSAGE_DEP(CABAL_FOUND "Cabal missing")
-message(STATUS " Library features:")
-message(STATUS " Build shared libraries: ${WITH_SHARED_LIB}")
-message(STATUS " Build static libraries: ${WITH_STATIC_LIB}")
-message(STATUS " Build with Boost static link library: ${WITH_BOOST_STATIC}")
-message(STATUS " Build with Boost thread support: ${WITH_BOOSTTHREADS}")
-message(STATUS " Build with boost/tr1/functional (forced) ${WITH_BOOST_FUNCTIONAL}")
-message(STATUS " Build with boost/smart_ptr (forced) ${WITH_BOOST_SMART_PTR}")
-message(STATUS " Build with C++ std::thread support: ${WITH_STDTHREADS}")
-message(STATUS " Build with libevent support: ${WITH_LIBEVENT}")
-message(STATUS " Build with OpenSSL support: ${WITH_OPENSSL}")
-message(STATUS " Build with Qt4 support: ${WITH_QT4}")
-message(STATUS " Build with Qt5 support: ${WITH_QT5}")
-message(STATUS " Build with ZLIB support: ${WITH_ZLIB}")
+message(STATUS)
message(STATUS "----------------------------------------------------------")
endmacro(PRINT_CONFIG_SUMMARY)
diff --git a/build/cmake/DefinePlatformSpecifc.cmake b/build/cmake/DefinePlatformSpecifc.cmake
index a809c07..c0bb529 100644
--- a/build/cmake/DefinePlatformSpecifc.cmake
+++ b/build/cmake/DefinePlatformSpecifc.cmake
@@ -20,8 +20,41 @@
# Uncomment this to show some basic cmake variables about platforms
# include (NewPlatformDebug)
+# For Debug build types, append a "d" to the library names.
+set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Set debug library postfix" FORCE)
+
+# basic options
+foreach(lang IN ITEMS C CXX)
+ if(CMAKE_${lang}_COMPILER_ID STREQUAL "Clang")
+ set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} -Wall")
+ set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} -ferror-limit=1")
+ elseif(CMAKE_${lang}_COMPILER_ID STREQUAL "GNU")
+ set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} -Wall -Wextra")
+ set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} -fmax-errors=1")
+ elseif(CMAKE_${lang}_COMPILER_ID STREQUAL "MSVC")
+ set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} /MP") # parallel build
+ set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} /W3") # warning level 3
+ include(CheckCXXCompilerFlag)
+ set(CMAKE_REQUIRED_QUIET ON)
+ check_cxx_compiler_flag("/source-charset:utf-8" res_var)
+ if (res_var)
+ set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} /source-charset:utf-8")
+ endif()
+ check_cxx_compiler_flag("/execution-charset:utf-8" res_var)
+ if (res_var)
+ set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} /execution-charset:utf-8")
+ endif()
+ add_definitions("-DUNICODE -D_UNICODE")
+ endif()
+endforeach()
+
# Visual Studio specific options
if(MSVC)
+ # Allow for shared library builds
+ if(BUILD_SHARED_LIBS)
+ set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON CACHE TYPE BOOL FORCE)
+ endif()
+
#For visual studio the library naming is as following:
# Dynamic libraries:
# - thrift.dll for release library
@@ -36,11 +69,6 @@
#
# the same holds for other libraries like libthriftz etc.
- # For Debug build types, append a "d" to the library names.
- set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Set debug library postfix" FORCE)
- set(CMAKE_RELEASE_POSTFIX "" CACHE STRING "Set release library postfix" FORCE)
- set(CMAKE_RELWITHDEBINFO_POSTFIX "" CACHE STRING "Set release library postfix" FORCE)
-
# Build using /MT option instead of /MD if the WITH_MT options is set
if(WITH_MT)
set(CompilerFlags
@@ -56,30 +84,13 @@
foreach(CompilerFlag ${CompilerFlags})
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
endforeach()
- set(STATIC_POSTFIX "mt" CACHE STRING "Set static library postfix" FORCE)
+ set(THRIFT_RUNTIME_POSTFIX "mt" CACHE STRING "Set runtime library postfix" FORCE)
else(WITH_MT)
- set(STATIC_POSTFIX "md" CACHE STRING "Set static library postfix" FORCE)
+ set(THRIFT_RUNTIME_POSTFIX "md" CACHE STRING "Set runtime library postfix" FORCE)
endif(WITH_MT)
# Disable boost auto linking pragmas - cmake includes the right files
add_definitions("-DBOOST_ALL_NO_LIB")
-
- # Windows build does not know how to make a shared library yet
- # as there are no __declspec(dllexport) or exports files in the project.
- if (WITH_SHARED_LIB)
- message (FATAL_ERROR "Windows build does not support shared library output yet, please set -DWITH_SHARED_LIB=off")
- endif()
-
- add_definitions("/MP") # parallel build
- add_definitions("/W3") # warning level 3
-
- # VS2010 does not provide inttypes which we need for "PRId64" used in many places
- find_package(Inttypes)
- if (Inttypes_FOUND)
- include_directories(${INTTYPES_INCLUDE_DIRS})
- # OpenSSL conflicts with the definition of PRId64 unless it is defined first
- add_definitions("/FIinttypes.h")
- endif ()
elseif(UNIX)
find_program( MEMORYCHECK_COMMAND valgrind )
set( MEMORYCHECK_COMMAND_OPTIONS "--gen-suppressions=all --leak-check=full" )
@@ -89,13 +100,6 @@
add_definitions("-D__STDC_FORMAT_MACROS")
add_definitions("-D__STDC_LIMIT_MACROS")
-# WITH_*THREADS selects which threading library to use
-if(WITH_BOOSTTHREADS)
- add_definitions("-DUSE_BOOST_THREAD=1")
-elseif(WITH_STDTHREADS)
- add_definitions("-DUSE_STD_THREAD=1")
-endif()
-
# C++ Language Level
set(CXX_LANGUAGE_LEVEL "C++${CMAKE_CXX_STANDARD}")
if (CMAKE_CXX_STANDARD_REQUIRED)
@@ -105,25 +109,8 @@
endif()
if (CMAKE_CXX_EXTENSIONS)
string(CONCAT CXX_LANGUAGE_LEVEL "${CXX_LANGUAGE_LEVEL} [with compiler-specific extensions]")
-else()
- if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND NOT MINGW)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-variadic-macros -Wno-long-long")
- endif()
- if ((CMAKE_CXX_COMPILER_ID MATCHES "Clang") AND NOT MINGW)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++11-long-long")
- endif()
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-register")
endif()
-
-# Building WITH_PLUGIN requires boost memory operations, for now, and gcc >= 4.8
-if (WITH_PLUGIN)
- if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8")
- message(SEND_ERROR "Thrift compiler plug-in support is not possible with older gcc ( < 4.8 ) compiler")
- endif()
- message(STATUS "Forcing use of boost::smart_ptr to build WITH_PLUGIN")
- add_definitions("-DFORCE_BOOST_SMART_PTR=1")
-endif()
-
diff --git a/build/cmake/FindClangTools.cmake b/build/cmake/FindClangTools.cmake
new file mode 100644
index 0000000..b72bea7
--- /dev/null
+++ b/build/cmake/FindClangTools.cmake
@@ -0,0 +1,28 @@
+# - Try to find Clang tools
+#
+# The following are set after configuration is done:
+# clang-tidy_FOUND
+# ClangTools::clang-tidy
+# clang-apply-replacements_FOUND
+# ClangTools::clang-apply-replacements
+# run-clang-tidy_FOUND
+# ClangTools::run-clang-tidy
+
+include_guard()
+include(FindPackageHandleStandardArgs)
+
+foreach(program_name IN ITEMS clang-tidy clang-apply-replacements)
+ find_program(${program_name}_BINARY NAMES ${program_name}-devel ${program_name}-8 ${program_name} PATH_SUFFIXES "LLVM/bin")
+ find_package_handle_standard_args(${program_name} DEFAULT_MSG ${program_name}_BINARY)
+ if(${program_name}_FOUND AND NOT TARGET ClangTools::${program_name})
+ add_executable(ClangTools::${program_name} IMPORTED)
+ set_property(TARGET ClangTools::${program_name} PROPERTY IMPORTED_LOCATION "${${program_name}_BINARY}")
+ endif()
+endforeach()
+
+find_program(run-clang-tidy_BINARY NAMES run-clang-tidy run-clang-tidy.py PATH_SUFFIXES "LLVM/bin" "llvm-devel/share/clang")
+find_package_handle_standard_args(run-clang-tidy DEFAULT_MSG run-clang-tidy_BINARY)
+if(run-clang-tidy_FOUND AND NOT TARGET ClangTools::run-clang-tidy)
+ add_executable(ClangTools::run-clang-tidy IMPORTED)
+ set_property(TARGET ClangTools::run-clang-tidy PROPERTY IMPORTED_LOCATION "${run-clang-tidy_BINARY}")
+endif()
diff --git a/build/cmake/GenerateConfigModule.cmake b/build/cmake/GenerateConfigModule.cmake
new file mode 100644
index 0000000..9533c82
--- /dev/null
+++ b/build/cmake/GenerateConfigModule.cmake
@@ -0,0 +1,44 @@
+#
+# 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.
+#
+
+include(CMakePackageConfigHelpers)
+set(PACKAGE_INCLUDE_INSTALL_DIR "${includedir}/thrift")
+set(PACKAGE_CMAKE_INSTALL_DIR "${cmakedir}/thrift")
+set(PACKAGE_BIN_INSTALL_DIR "${exec_prefix}")
+
+# In CYGWIN enviroment below commands does not work properly
+if (NOT CYGWIN)
+ configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/ThriftConfig.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/ThriftConfig.cmake"
+ INSTALL_DESTINATION "${CMAKE_INSTALL_DIR}/thrift"
+ PATH_VARS
+ PACKAGE_INCLUDE_INSTALL_DIR
+ PACKAGE_CMAKE_INSTALL_DIR
+ PACKAGE_BIN_INSTALL_DIR
+ )
+
+ write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/ThriftConfigVersion.cmake"
+ VERSION ${thrift_VERSION_MAJOR}.${thrift_VERSION_MINOR}.${thrift_VERSION_PATCH}
+ COMPATIBILITY SameMajorVersion
+ )
+
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ThriftConfig.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/ThriftConfigVersion.cmake"
+ DESTINATION "${CMAKE_INSTALL_DIR}/thrift")
+endif()
diff --git a/build/cmake/README-MSYS2.md b/build/cmake/README-MSYS2.md
index 02679e6..07cad92 100644
--- a/build/cmake/README-MSYS2.md
+++ b/build/cmake/README-MSYS2.md
@@ -43,7 +43,7 @@
cmake -G"MinGW Makefiles" -DCMAKE_MAKE_PROGRAM=/mingw64/bin/mingw32-make \
-DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc.exe \
-DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++.exe \
- -DWITH_BOOSTTHREADS=ON -DWITH_LIBEVENT=OFF \
+ -DWITH_LIBEVENT=OFF \
-DWITH_SHARED_LIB=OFF -DWITH_STATIC_LIB=ON \
-DWITH_JAVA=OFF -DWITH_PYTHON=OFF -DWITH_PERL=OFF \
../thrift
diff --git a/build/cmake/README.md b/build/cmake/README.md
index ebc4f7d..a0eb859 100644
--- a/build/cmake/README.md
+++ b/build/cmake/README.md
@@ -1,6 +1,7 @@
-# Apache Thrift - CMake build
+# Apache Thrift - CMake Build
## Goal
+
Extend Apache Thrift's *make cross* approach to the build system.
Due to growing the field of operating system support, a proper executable
@@ -11,12 +12,26 @@
As nice side benefit of CMake is the generation of development environment
specific soultion files. => No solution files within source tree.
+## Prerequisites
+
+These are language-specific, however for C++ you must provide:
+
+- Boost
+- OpenSSL
+
+You may optionally provide:
+
+- libevent
+- zlib
## Usage
-just do this:
- mkdir cmake-build && cd cmake-build
- cmake ..
+To use CMake you first create an out-of-tree build directory, then use
+CMake to generate a build framework, then build:
+
+ mkdir /tmp/build
+ cd /tmp/build
+ cmake /location/to/thrift
if you use a specific toolchain pass it to cmake, the same for options:
@@ -25,13 +40,6 @@
cmake -DTHRIFT_COMPILER_HS=OFF ..
cmake -DWITH_ZLIB=ON ..
-or on Windows
-
- cmake -G "Visual Studio 12 2013 Win64" \
- -DBOOST_ROOT=C:/3rdparty/boost_1_58_0 \
- -DZLIB_ROOT=C:/3rdparty/zlib128-dll \
- -DWITH_SHARED_LIB=off -DWITH_BOOSTTHREADS=ON ..
-
and open the development environment you like with the solution or do this:
make
@@ -39,15 +47,25 @@
make cross
make dist
-to generate an installer and distribution package do this:
+or on Windows, the following will produce a solution file you can use
+inside Visual Studio:
+
+ cmake -G "Visual Studio 15 2017 Win64" \
+ -DBOOST_ROOT=C:/3rdparty/boost_1_69_0 \
+ -DBOOST_LIBRARYDIR=C:/3rdparty/boost_1_69_0/lib64-msvc-14.1^
+ -DZLIB_ROOT=C:/3rdparty/zlib-1.2.11
+
+<!--
+To generate an installer and distribution package do this:
cpack
+-->
## TODO
+
* git hash or tag based versioning depending on source state
* build tutorial
* build test
-* with/without language lib/<lang>/
* enable/disable
* make cross
* make dist (create an alias to make package_source)
@@ -57,4 +75,4 @@
* libthrift
* tutorial
* test
-* merge into /README.md
+* merge into /README.md
\ No newline at end of file
diff --git a/build/cmake/StaticCodeAnalysis.cmake b/build/cmake/StaticCodeAnalysis.cmake
new file mode 100644
index 0000000..3356c76
--- /dev/null
+++ b/build/cmake/StaticCodeAnalysis.cmake
@@ -0,0 +1,9 @@
+find_package(ClangTools QUIET)
+if(clang-tidy_FOUND AND run-clang-tidy_FOUND AND NOT TARGET do_run_clang_tidy)
+ add_custom_target(
+ do_run_clang_tidy
+ COMMAND ClangTools::run-clang-tidy -clang-tidy-binary "$<TARGET_FILE:ClangTools::clang-tidy>" -p ${CMAKE_BINARY_DIR} "-quiet" > ./run-clang-tidy.txt
+ DEPENDS ${CMAKE_BINARY_DIR}/compile_commands.json
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ )
+endif()
diff --git a/build/cmake/ThriftConfig.cmake.in b/build/cmake/ThriftConfig.cmake.in
new file mode 100644
index 0000000..c304da0
--- /dev/null
+++ b/build/cmake/ThriftConfig.cmake.in
@@ -0,0 +1,42 @@
+#
+# 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.
+#
+
+set(THRIFT_VERSION ${thrift_VERSION})
+
+@PACKAGE_INIT@
+
+set_and_check(THRIFT_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
+set_and_check(THRIFT_CMAKE_DIR "@PACKAGE_CMAKE_INSTALL_DIR@")
+set_and_check(THRIFT_BIN_DIR "@PACKAGE_BIN_INSTALL_DIR@")
+
+if (NOT TARGET thrift::thrift)
+ include("${THRIFT_CMAKE_DIR}/thriftTargets.cmake")
+endif()
+
+set(THRIFT_LIBRARIES thrift::thrift)
+
+if ("${THRIFT_LIBRARIES}" STREQUAL "")
+ message(FATAL_ERROR "thrift libraries were not found")
+endif()
+
+if (NOT Thrift_FIND_QUIETLY)
+ message(STATUS "Found thrift: ${PACKAGE_PREFIX_DIR}")
+endif()
+
+check_required_components(Thrift)
diff --git a/build/cmake/ThriftMacros.cmake b/build/cmake/ThriftMacros.cmake
index f837f94..d068b2a 100644
--- a/build/cmake/ThriftMacros.cmake
+++ b/build/cmake/ThriftMacros.cmake
@@ -17,89 +17,46 @@
# under the License.
#
-
-set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Set debug library postfix" FORCE)
-
+macro(ADD_PKGCONFIG_THRIFT name)
+ configure_file("${name}.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/${name}.pc" @ONLY)
+ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${name}.pc"
+ DESTINATION "${PKGCONFIG_INSTALL_DIR}")
+endmacro(ADD_PKGCONFIG_THRIFT)
macro(ADD_LIBRARY_THRIFT name)
-
-if(WITH_SHARED_LIB)
- add_library(${name} SHARED ${ARGN})
+ add_library(${name} ${ARGN})
set_target_properties(${name} PROPERTIES
- OUTPUT_NAME ${name}
- VERSION ${thrift_VERSION}
- SOVERSION ${thrift_VERSION} )
- #set_target_properties(${name} PROPERTIES PUBLIC_HEADER "${thriftcpp_HEADERS}")
- install(TARGETS ${name}
+ OUTPUT_NAME ${name}${THRIFT_RUNTIME_POSTFIX} # windows link variants (/MT, /MD, /MTd, /MDd) get different names
+ VERSION ${thrift_VERSION} )
+ # set_target_properties(${name} PROPERTIES PUBLIC_HEADER "${thriftcpp_HEADERS}")
+ install(TARGETS ${name} EXPORT "${name}Targets"
RUNTIME DESTINATION "${BIN_INSTALL_DIR}"
LIBRARY DESTINATION "${LIB_INSTALL_DIR}"
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}"
PUBLIC_HEADER DESTINATION "${INCLUDE_INSTALL_DIR}")
-endif()
-if(WITH_STATIC_LIB)
- add_library(${name}_static STATIC ${ARGN})
- set_target_properties(${name}_static PROPERTIES
- OUTPUT_NAME ${name}${STATIC_POSTFIX}
- VERSION ${thrift_VERSION}
- SOVERSION ${thrift_VERSION} )
- install(TARGETS ${name}_static
- RUNTIME DESTINATION "${BIN_INSTALL_DIR}"
- LIBRARY DESTINATION "${LIB_INSTALL_DIR}"
- ARCHIVE DESTINATION "${LIB_INSTALL_DIR}"
- PUBLIC_HEADER DESTINATION "${INCLUDE_INSTALL_DIR}")
-endif()
+ export(EXPORT "${name}Targets"
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/${name}/${name}Targets.cmake"
+ NAMESPACE "${name}::")
-endmacro(ADD_LIBRARY_THRIFT)
-
+ install(EXPORT "${name}Targets"
+ FILE "${name}Targets.cmake"
+ NAMESPACE "${name}::"
+ DESTINATION "${CMAKE_INSTALL_DIR}/thrift")
+endmacro()
macro(TARGET_INCLUDE_DIRECTORIES_THRIFT name)
-
-if(WITH_SHARED_LIB)
target_include_directories(${name} ${ARGN})
-endif()
-
-if(WITH_STATIC_LIB)
- target_include_directories(${name}_static ${ARGN})
-endif()
-
-endmacro(TARGET_INCLUDE_DIRECTORIES_THRIFT)
-
+endmacro()
macro(TARGET_LINK_LIBRARIES_THRIFT name)
-
-if(WITH_SHARED_LIB)
target_link_libraries(${name} ${ARGN})
-endif()
-
-if(WITH_STATIC_LIB)
- target_link_libraries(${name}_static ${ARGN})
-endif()
-
-endmacro(TARGET_LINK_LIBRARIES_THRIFT)
-
+endmacro()
macro(LINK_AGAINST_THRIFT_LIBRARY target libname)
-
-if (WITH_SHARED_LIB)
target_link_libraries(${target} ${libname})
-elseif (WITH_STATIC_LIB)
- target_link_libraries(${target} ${libname}_static)
-else()
- message(FATAL "Not linking with shared or static libraries?")
-endif()
-
-endmacro(LINK_AGAINST_THRIFT_LIBRARY)
-
+endmacro()
macro(TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY target libname)
-
-if(WITH_SHARED_LIB)
target_link_libraries(${target} ${ARGN} ${libname})
-endif()
-
-if(WITH_STATIC_LIB)
- target_link_libraries(${target}_static ${ARGN} ${libname}_static)
-endif()
-
-endmacro(TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY)
+endmacro()
diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in
index 39d8270..a3d6642 100644
--- a/build/cmake/config.h.in
+++ b/build/cmake/config.h.in
@@ -64,12 +64,6 @@
see: aclocal/ac_prog_bison.m4 */
#cmakedefine BISON_USE_PARSER_H_EXTENSION 1
-/* replaces POSIX pthread by boost::thread */
-#cmakedefine USE_BOOST_THREAD 1
-
-/* replaces POSIX pthread by std::thread */
-#cmakedefine USE_STD_THREAD 1
-
/* Define to 1 if strerror_r returns char *. */
#cmakedefine STRERROR_R_CHAR_P 1
diff --git a/build/docker/README.md b/build/docker/README.md
index d0a8388..b65f74b 100644
--- a/build/docker/README.md
+++ b/build/docker/README.md
@@ -167,32 +167,31 @@
| Language | ubuntu-xenial | ubuntu-bionic | Notes |
| :-------- | :------------ | :------------ | :---- |
-| as of | Mar 06, 2018 | Jul 6, 2018 | |
-| as3 | | | Not in CI |
+| as of | Mar 06, 2018 | Jan 21, 2019 | |
+| as3 | | 4.6.0 | |
| C++ gcc | 5.4.0 | 7.3.0 | |
| C++ clang | 3.8 | 6.0 | |
| C# (mono) | 4.2.1.0 | 4.6.2.7 | |
| c_glib | 2.48.2 | 2.56.0 | |
-| cl (sbcl) | | 1.4.9 | |
-| cocoa | | | Not in CI |
-| d | 2.075.1 | 2.081.0 | |
-| dart | 1.22.1 | 1.24.3 | |
+| cl (sbcl) | | 1.4.15 | |
+| d | 2.075.1 | 2.083.1 | |
+| dart | 1.24.3 | 2.1.0 | |
| delphi | | | Not in CI |
-| dotnet | 2.1.4 | 2.1.301 | |
+| dotnet | 2.1.503 | 2.2.103 | |
| erlang | 18.3 | 20.2.2 | |
-| go | 1.7.6 | 1.10.3 | |
+| go | 1.7.6 | 1.11.4 | |
| haskell | 7.10.3 | 8.0.2 | |
| haxe | 3.2.1 | 3.4.4 | THRIFT-4352: avoid 3.4.2 |
-| java | 1.8.0_151 | 1.8.0_171 | |
+| java | 1.8.0_191 | 1.8.0_191 | |
| js | | | Unsure how to look for version info? |
| lua | 5.2.4 | 5.2.4 | Lua 5.3: see THRIFT-4386 |
-| nodejs | 6.13.0 | 8.11.3 | |
+| nodejs | 6.16.0 | 8.15.0 | |
| ocaml | | 4.05.0 | THRIFT-4517: ocaml 4.02.3 on xenial appears broken |
| perl | 5.22.1 | 5.26.1 | |
-| php | 7.0.22 | 7.2.5 | |
+| php | 7.0.32 | 7.2.10 | |
| python | 2.7.12 | 2.7.15rc1 | |
-| python3 | 3.5.2 | 3.6.5 | |
+| python3 | 3.5.2 | 3.6.7 | |
| ruby | 2.3.1p112 | 2.5.1p57 | |
-| rust | 1.17.0 | 1.24.1 | |
+| rust | 1.30.0 | 1.30.0 | |
| smalltalk | | | Not in CI |
-| swift | | | Not in CI |
+| swift | | 4.2.1 | |
diff --git a/build/docker/msvc2017/Dockerfile b/build/docker/msvc2017/Dockerfile
new file mode 100644
index 0000000..a2b3cd7
--- /dev/null
+++ b/build/docker/msvc2017/Dockerfile
@@ -0,0 +1,103 @@
+# escape=`
+#
+# Licensed 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.
+#
+
+FROM microsoft/dotnet-framework:4.7.1
+
+# Restore the default Windows shell for correct batch processing below.
+SHELL ["cmd", "/S", "/C"]
+
+# Install Build Tools excluding workloads and components with known issues.
+ADD https://aka.ms/vs/15/release/vs_buildtools.exe C:\TEMP\vs_buildtools.exe
+RUN C:\TEMP\vs_buildtools.exe --quiet --wait --norestart --nocache `
+ --installPath C:\BuildTools `
+ --all `
+ --remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
+ --remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
+ --remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
+ --remove Microsoft.VisualStudio.Component.Windows81SDK `
+ || IF "%ERRORLEVEL%"=="3010" EXIT 0
+RUN DEL C:\TEMP\vs_buildtools.exe
+
+# Install CMake
+ADD https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-win64-x64.msi C:\TEMP\cmake.msi
+RUN msiexec.exe /i C:\TEMP\cmake.msi /qn && `
+ SETX PATH "%PATH%;C:\Program Files\CMake\bin" && `
+ DEL C:\TEMP\cmake.msi
+
+# Install boost (for the thrift runtime library build)
+ADD https://boost.teeks99.com/bin/1.69.0/boost_1_69_0-msvc-14.1-64.exe C:\TEMP\boost.exe
+RUN C:\TEMP\boost.exe /DIR="C:\Libraries\boost_1_69_0" /SILENT && `
+ DEL C:\TEMP\boost.exe
+
+# Install chocolatey
+RUN @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" `
+ -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command `
+ "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" `
+ && SETX PATH "%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
+
+# Install winflexbison (for the thrift compiler build)
+RUN choco install winflexbison3 -y
+
+# Install 7zip and curl (used by the libevent and zlib build scripts)
+RUN choco install 7zip curl -y
+
+# Install libevent
+COPY appveyor\build-libevent.bat C:\TEMP\build-libevent.bat
+ENV LIBEVENT_VERSION=2.1.8
+ENV WIN3P=C:\TEMP\WIN3P
+RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 && `
+ MKDIR C:\TEMP\WIN3P && `
+ C:\TEMP\build-libevent.bat && `
+ MKDIR C:\Libraries\libevent-%LIBEVENT_VERSION% && `
+ MOVE C:\TEMP\WIN3P\libevent-%LIBEVENT_VERSION%-stable\include C:\Libraries\libevent-%LIBEVENT_VERSION% && `
+ MOVE C:\TEMP\WIN3P\libevent-%LIBEVENT_VERSION%-stable\lib C:\Libraries\libevent-%LIBEVENT_VERSION% && `
+ RMDIR /S /Q C:\TEMP\WIN3P
+
+# Install zlib
+COPY appveyor\build-zlib.bat C:\TEMP\build-zlib.bat
+ENV ZLIB_VERSION=1.2.11
+ENV WIN3P=C:\TEMP\WIN3P
+RUN C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 && `
+ MKDIR C:\TEMP\WIN3P && `
+ C:\TEMP\build-zlib.bat && `
+ MOVE C:\TEMP\WIN3P\zlib-inst C:\Libraries\zlib-%ZLIB_VERSION% && `
+ RMDIR /S /Q C:\TEMP\WIN3P
+
+# Install OpenSSL 1.1.0
+ADD http://slproweb.com/download/Win64OpenSSL-1_1_0j.exe C:\TEMP\openssl.exe
+RUN C:\TEMP\openssl.exe /silent && `
+ DEL C:\TEMP\openssl.exe
+
+# Install java
+RUN choco install jdk8 -y
+
+# Install haskell
+RUN choco install ghc -y
+
+# Install python3
+RUN choco install python3 -y
+
+# Install Adobe Flex 4.6 SDK and set FLEX_HOME so it can be found
+ADD http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip C:\Adobe\Flex\SDK\4.6\SDK.zip
+RUN CD C:\Adobe\Flex\SDK\4.6 && `
+ 7z x SDK.zip && `
+ DEL SDK.zip && `
+ SETX FLEX_HOME "C:\Adobe\Flex\SDK\4.6"
+
+# Start developer command prompt with any other commands specified.
+ENTRYPOINT C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 &&
+
+# Default to PowerShell if no other command specified.
+CMD ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]
diff --git a/build/docker/msvc2017/README.md b/build/docker/msvc2017/README.md
new file mode 100644
index 0000000..0c882d7
--- /dev/null
+++ b/build/docker/msvc2017/README.md
@@ -0,0 +1,50 @@
+# Building Thrift using Docker for Windows
+
+The build image is very large (just under 30GB) so plan accordingly.
+Once Microsoft supports build tools in nano, it should get better.
+
+Install Docker for Windows and switch to Windows container mode.
+
+Pull from docker hub:
+
+ PS C:\> docker pull thrift/thrift-build:msvc2017
+
+or build in a docker for windows environment:
+
+ PS C:\Thrift> docker build -t thrift/thrift-build:msvc2017 -f build\docker\msvc2017\Dockerfile build\
+
+The following directories are used inside the container:
+
+ C:\Build the out-of-tree build directory
+ C:\Install the install target directory
+ C:\Thrift the source tree
+
+You can override these as docker volumes if desired.
+
+### Compiler
+
+To build a portable windows thrift compiler (with a statically linked
+runtime) and get it placed into C:\install:
+
+ docker run -v C:\thrift:C:\thrift^
+ -v C:\install:C:\install^
+ --rm -t thrift/thrift-build:msvc2017^
+ C:\thrift\build\docker\msvc2017\build-compiler.bat
+
+The end result is a portable windows thrift compiler located at
+
+ C:\Install\bin\thrift.exe
+
+If you run it through the [Dependency Walker](http://www.dependencywalker.com/)
+you will see it only depends on KERNEL32.DLL which means the runtime is statically
+linked, so the executable is portable and self-contained. This is how the
+windows thrift compiler is built for each Apache Thrift release.
+
+### Libraries
+
+To build, test everything and get the C++ SDK placed into C:\install:
+
+ docker run -v C:\thrift:C:\thrift^
+ -v C:\install:C:\install^
+ -m 4096 --rm -t thrift/thrift-build:msvc2017^
+ C:\thrift\build\docker\msvc2017\build.bat
\ No newline at end of file
diff --git a/build/docker/msvc2017/build-compiler.bat b/build/docker/msvc2017/build-compiler.bat
new file mode 100644
index 0000000..5534428
--- /dev/null
+++ b/build/docker/msvc2017/build-compiler.bat
@@ -0,0 +1,44 @@
+::
+:: Licensed 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.
+::
+
+::
+:: Build script example for inside the windows docker container
+::
+:: C:\build is the out-of-tree build directory
+:: C:\install is the location where artifacts are placed
+:: C:\thrift is where the sources are
+::
+
+:: Make and go into the out-of-tree directory
+IF NOT EXIST C:\build (MKDIR C:\build)
+cd c:\build
+
+:: Generate the out-of-tree build files
+cmake^
+ -DBOOST_ROOT=C:\Libraries\boost_1_69_0^
+ -DBOOST_LIBRARYDIR=C:\Libraries\boost_1_69_0\lib64-msvc-14.1^
+ -DBUILD_LIBRARIES=OFF^
+ -DCMAKE_BUILD_TYPE=Release^
+ -DCMAKE_INSTALL_PREFIX=C:\install^
+ -DWITH_MT=ON^
+ c:\thrift || EXIT /B
+
+:: Build
+cmake --build . --target thrift-compiler --config Release || EXIT /B
+
+:: Test
+cmake --build . --target check || EXIT /B
+
+:: Install
+cmake --build . --target install
\ No newline at end of file
diff --git a/build/docker/msvc2017/build.bat b/build/docker/msvc2017/build.bat
new file mode 100644
index 0000000..018805b
--- /dev/null
+++ b/build/docker/msvc2017/build.bat
@@ -0,0 +1,45 @@
+::
+:: Licensed 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.
+::
+
+::
+:: Build script example for inside the windows docker container
+::
+:: C:\build is the out-of-tree build directory
+:: C:\install is the location where artifacts are placed
+:: C:\thrift is where the sources are
+::
+
+:: Make and go into the out-of-tree directory
+IF NOT EXIST C:\build (MKDIR C:\build)
+cd c:\build
+
+:: Generate the out-of-tree build files
+cmake^
+ -DBOOST_ROOT=C:\Libraries\boost_1_69_0^
+ -DBOOST_LIBRARYDIR=C:\Libraries\boost_1_69_0\lib64-msvc-14.1^
+ -DFLEX_HOME=C:\Adobe\Flex\SDK\4.6^
+ -DLIBEVENT_ROOT=C:\Libraries\libevent-2.1.8^
+ -DZLIB_ROOT=C:\Libraries\zlib-1.2.11^
+ -DCMAKE_BUILD_TYPE=Release^
+ -DCMAKE_INSTALL_PREFIX=C:\install^
+ c:\thrift || EXIT /B
+
+:: Build
+cmake --build . --config Release || EXIT /B
+
+:: Test
+cmake --build . --target check || EXIT /B
+
+:: Install
+cmake --build . --target install
diff --git a/build/docker/old/debian-jessie/Dockerfile b/build/docker/old/debian-jessie/Dockerfile
index 7bc74fc..941b4bb 100644
--- a/build/docker/old/debian-jessie/Dockerfile
+++ b/build/docker/old/debian-jessie/Dockerfile
@@ -79,6 +79,7 @@
RUN apt-get install -y --no-install-recommends \
`# Ruby dependencies` \
ruby \
+ ruby-bundler \
ruby-dev \
`# Perl dependencies` \
libbit-vector-perl \
diff --git a/build/docker/ubuntu-artful/Dockerfile b/build/docker/old/ubuntu-artful/Dockerfile
similarity index 100%
rename from build/docker/ubuntu-artful/Dockerfile
rename to build/docker/old/ubuntu-artful/Dockerfile
diff --git a/build/docker/scripts/cmake.sh b/build/docker/scripts/cmake.sh
index ccc311e..eb384d5 100755
--- a/build/docker/scripts/cmake.sh
+++ b/build/docker/scripts/cmake.sh
@@ -19,5 +19,4 @@
done
$MAKEPROG -j3
cpack
-ctest -VV -E "(python_test)"
-# disabled cmake python_test for now since it fails in travis under centos
+ctest -VV
diff --git a/build/docker/scripts/sca.sh b/build/docker/scripts/sca.sh
index 16d5826..42128fc 100755
--- a/build/docker/scripts/sca.sh
+++ b/build/docker/scripts/sca.sh
@@ -39,15 +39,7 @@
cppcheck --force --quiet --inline-suppr --error-exitcode=1 -j2 lib/c_glib/src lib/c_glib/test test/c_glib/src tutorial/c_glib
# Python code style
-flake8 --ignore=W504,E501 lib/py
-flake8 --exclude=tutorial/py/build tutorial/py
-# THRIFT-4371 : generated files are excluded because they haven't been scrubbed yet
-flake8 --ignore=E501 --exclude="*/gen-py*/*",test/py/build test/py
-flake8 test/py.twisted
-flake8 test/py.tornado
-flake8 --ignore=E501 test/test.py
-flake8 --ignore=E501,E722 test/crossrunner
-flake8 test/features
+flake8
# PHP code style
composer install --quiet
diff --git a/build/docker/ubuntu-bionic/Dockerfile b/build/docker/ubuntu-bionic/Dockerfile
index aef35c5..c8131bb 100644
--- a/build/docker/ubuntu-bionic/Dockerfile
+++ b/build/docker/ubuntu-bionic/Dockerfile
@@ -15,7 +15,7 @@
# Using all stock Ubuntu Bionic packaging except for:
# - cl: want latest
# - d: dmd does not come with Ubuntu
-# - dart: does not come with Ubuntu. Pinned to last 1.x release
+# - dart: does not come with Ubuntu - we use 2.x here
# - dotnet: does not come with Ubuntu
# - go: want latest
# - nodejs: want v8, bionic comes with v6
@@ -46,7 +46,6 @@
RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \
/etc/apt/sources.list.d/dart_stable.list
-ENV DART_VERSION 1.24.3-1
# dotnet (netcore)
RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \
@@ -69,6 +68,9 @@
debhelper \
flex \
gdb \
+ libasound2 \
+ libatk-bridge2.0-0 \
+ libgtk-3-0 \
llvm \
ninja-build \
pkg-config \
@@ -97,11 +99,11 @@
`# csharp (mono) dependencies` \
mono-devel
-ENV SBCL_VERSION 1.4.12
+ENV SBCL_VERSION 1.4.15
RUN \
`# Common Lisp (sbcl) dependencies` \
curl --version && \
- curl -O -J -L https://kent.dl.sourceforge.net/project/sbcl/sbcl/${SBCL_VERSION}/sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 && \
+ curl -o sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 -J -L https://sourceforge.net/projects/sbcl/files/sbcl/${SBCL_VERSION}/sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2/download?use_mirror=managedway# && \
tar xjf sbcl-${SBCL_VERSION}-x86-64-linux-binary.tar.bz2 && \
cd sbcl-${SBCL_VERSION}-x86-64-linux && \
./install.sh && \
@@ -109,23 +111,24 @@
cd .. && \
rm -rf sbcl*
-ENV D_VERSION 2.082.1
-ENV DMD_DEB dmd_2.082.1-0_amd64.deb
+ENV D_VERSION 2.083.1
+ENV DMD_DEB dmd_2.083.1-0_amd64.deb
RUN \
`# D dependencies` \
wget -q http://downloads.dlang.org/releases/2.x/${D_VERSION}/${DMD_DEB} && \
dpkg --install ${DMD_DEB} && \
rm -f ${DMD_DEB} && \
mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \
- curl -sSL https://github.com/D-Programming-Deimos/libevent/archive/master.tar.gz| tar xz && \
- mv libevent-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \
- mv libevent-master/C/* /usr/include/dmd/druntime/import/C/ && \
- rm -rf libevent-master && \
- curl -sSL https://github.com/jeking3/openssl/archive/tls_method.tar.gz| tar xz && \
- mv openssl-tls_method/deimos/* /usr/include/dmd/druntime/import/deimos/ && \
- mv openssl-tls_method/C/* /usr/include/dmd/druntime/import/C/ && \
- rm -rf openssl-tls_method
+ git clone -b 'v2.0.2+2.0.16' https://github.com/D-Programming-Deimos/libevent.git deimos-libevent-2.0 && \
+ mv deimos-libevent-2.0/deimos/* /usr/include/dmd/druntime/import/deimos/ && \
+ mv deimos-libevent-2.0/C/* /usr/include/dmd/druntime/import/C/ && \
+ rm -rf deimos-libevent-2.0 && \
+ git clone -b 'v2.0.0+1.1.0h' https://github.com/D-Programming-Deimos/openssl.git deimos-openssl-1.1.0h && \
+ mv deimos-openssl-1.1.0h/deimos/* /usr/include/dmd/druntime/import/deimos/ && \
+ mv deimos-openssl-1.1.0h/C/* /usr/include/dmd/druntime/import/C/ && \
+ rm -rf deimos-openssl-1.1.0h
+ENV DART_VERSION 2.1.0-1
RUN apt-get install -y --no-install-recommends \
`# Dart dependencies` \
dart=$DART_VERSION
@@ -133,7 +136,7 @@
RUN apt-get install -y --no-install-recommends \
`# dotnet core dependencies` \
- dotnet-sdk-2.1
+ dotnet-sdk-2.2
RUN apt-get install -y --no-install-recommends \
`# Erlang dependencies` \
@@ -148,9 +151,9 @@
libglib2.0-dev
# golang
-ENV GOLANG_VERSION 1.11.1
+ENV GOLANG_VERSION 1.12.1
ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
-ENV GOLANG_DOWNLOAD_SHA256 2871270d8ff0c8c69f161aaae42f9f28739855ff5c5204752a8d92a1c9f63993
+ENV GOLANG_DOWNLOAD_SHA256 2a3fdabf665496a0db5f41ec6af7a9b15a49fbe71a85a50ca38b1f13a103aeec
RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \
echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \
tar -C /usr/local -xzf golang.tar.gz && \
@@ -174,9 +177,8 @@
`# Java dependencies` \
ant \
ant-optional \
- openjdk-8-jdk \
- maven && \
- update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
+ maven \
+ openjdk-11-jdk-headless
RUN apt-get install -y --no-install-recommends \
`# Lua dependencies` \
@@ -215,6 +217,7 @@
php \
php-cli \
php-dev \
+ php-json \
php-pear \
re2c \
composer
@@ -253,10 +256,15 @@
ruby-dev \
ruby-bundler
-RUN apt-get install -y --no-install-recommends \
-`# Rust dependencies` \
- cargo \
- rustc
+# Rust dependencies
+RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y
+
+# Swift on Linux for cross tests
+RUN cd / && \
+ wget --quiet https://swift.org/builds/swift-4.2.1-release/ubuntu1804/swift-4.2.1-RELEASE/swift-4.2.1-RELEASE-ubuntu18.04.tar.gz && \
+ tar xf swift-4.2.1-RELEASE-ubuntu18.04.tar.gz --strip-components=1 && \
+ rm swift-4.2.1-RELEASE-ubuntu18.04.tar.gz && \
+ swift --version
# cppcheck-1.82 has a nasty cpp parser bug, so we're using something newer
RUN apt-get install -y --no-install-recommends \
diff --git a/build/docker/ubuntu-xenial/Dockerfile b/build/docker/ubuntu-xenial/Dockerfile
index 3372b4d..97aaaea 100644
--- a/build/docker/ubuntu-xenial/Dockerfile
+++ b/build/docker/ubuntu-xenial/Dockerfile
@@ -14,9 +14,9 @@
# Apache Thrift Docker build environment for Ubuntu Xenial
# Using all stock Ubuntu Xenial packaging except for:
# - d: does not come with Ubuntu so we're installing 2.075.1 for coverage
-# - dart: does not come with Ubuntu so we're installing 1.22.1 for coverage
+# - dart: does not come with Ubuntu so we're installing 1.24.3 for coverage
# - dotnet: does not come with Ubuntu
-# - go: Xenial comes with 1.6, but we need 1.7 or later
+# - go: Xenial comes with 1.6, but we need 1.10 or later
# - nodejs: Xenial comes with 4.2.6 which exits LTS April 2018, so we're installing 6.x
# - ocaml: causes stack overflow error, just started March 2018 not sure why
#
@@ -50,7 +50,6 @@
RUN curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \
/etc/apt/sources.list.d/dart_stable.list
-ENV DART_VERSION 1.22.1-1
# dotnet (core)
RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \
@@ -120,6 +119,7 @@
mv openssl-1.1.6-1.0.1g/C/* /usr/include/dmd/druntime/import/C/ && \
rm -rf openssl-1.1.6-1.0.1g
+ENV DART_VERSION 1.24.3-1
RUN apt-get install -y --no-install-recommends \
`# Dart dependencies` \
dart=$DART_VERSION
@@ -127,7 +127,7 @@
RUN apt-get install -y --no-install-recommends \
`# dotnet core dependencies` \
- dotnet-sdk-2.1.4
+ dotnet-sdk-2.1
RUN apt-get install -y --no-install-recommends \
`# Erlang dependencies` \
@@ -142,9 +142,9 @@
libglib2.0-dev
# golang
-ENV GOLANG_VERSION 1.7.6
+ENV GOLANG_VERSION 1.10.8
ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
-ENV GOLANG_DOWNLOAD_SHA256 ad5808bf42b014c22dd7646458f631385003049ded0bb6af2efc7f1f79fa29ea
+ENV GOLANG_DOWNLOAD_SHA256 d8626fb6f9a3ab397d88c483b576be41fa81eefcec2fd18562c87626dbb3c39e
RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \
echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && \
tar -C /usr/local -xzf golang.tar.gz && \
@@ -218,6 +218,7 @@
php7.0 \
php7.0-cli \
php7.0-dev \
+ php-json \
php-pear \
re2c \
composer
@@ -253,10 +254,8 @@
ruby-dev \
ruby-bundler
-RUN apt-get install -y --no-install-recommends \
-`# Rust dependencies` \
- cargo \
- rustc
+# Rust dependencies
+RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y
# Clean up
RUN rm -rf /var/cache/apt/* && \
diff --git a/build/fixchanges.sh b/build/fixchanges.sh
new file mode 100755
index 0000000..6c57b54
--- /dev/null
+++ b/build/fixchanges.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+
+#
+# fixchanges will take a file as input and look for text matching
+# the pattern [THRIFT-nnnn] (the number of digits is not important)
+# which is not a markdown link, and change it to be a markdown link.
+# The tool writes to stdout so you can redirect it to a temporary
+# file and then compare against the original file before replacing
+# it.
+#
+# This tool was developed after the 0.12.0 release to assist with
+# generation of CHANGES.md content.
+#
+
+while IFS='' read -r line || [[ -n "$line" ]]; do
+ if [[ "$line" =~ ^(.*)\[(THRIFT-[[:digit:]]+)\][^\(](.*)$ ]]; then
+ echo "${BASH_REMATCH[1]}[${BASH_REMATCH[2]}](https://issues.apache.org/jira/browse/${BASH_REMATCH[2]}) ${BASH_REMATCH[3]}"
+ else
+ echo "$line"
+ fi
+done < "$1"
diff --git a/build/travis/installCXXDependencies.sh b/build/travis/installCXXDependencies.sh
deleted file mode 100755
index ac3edf3..0000000
--- a/build/travis/installCXXDependencies.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-
-# 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.
-
-
-# Mainly aiming Travis CI's Ubuntu machines for now
-# see what we need: http://thrift.apache.org/docs/install/ubuntu
-
-# General dependencies
-sudo apt-add-repository "deb http://archive.ubuntu.com/ubuntu/ trusty main restricted" -y
-sudo apt-get update -qq
-
-sudo apt-get install -qq libpango-1.0-0 libqt4-dev qtbase5-dev qtbase5-dev-tools qt5-default libboost-dev libboost-test-dev libboost-program-options-dev libboost-system-dev libboost-filesystem-dev libboost-thread-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev make cmake git debhelper bc nsis ninja-build
-dpkg -S /usr/include/boost/version.hpp
diff --git a/build/travis/installDependencies.sh b/build/travis/installDependencies.sh
deleted file mode 100755
index eab8c6b..0000000
--- a/build/travis/installDependencies.sh
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/sh
-
-# 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.
-
-SCRIPTPATH=$( cd $(dirname $0) ; pwd -P )
-
-# Mainly aiming Travis CI's Ubuntu machines for now
-# see what we need: http://thrift.apache.org/docs/install/ubuntu
-
-# Java dependencies
-sudo apt-get install -qq ant openjdk-7-jdk
-sudo update-java-alternatives -s java-1.7.0-openjdk-amd64
-
-# Python dependencies
-sudo apt-get install -qq python-all python-all-dev python-all-dbg python-setuptools python-support python-twisted python-six python3-six
-
-# Ruby dependencies
-sudo apt-get install -qq ruby ruby-dev
-sudo gem install bundler rake
-
-# Perl dependencies
-sudo apt-get install -qq libbit-vector-perl libclass-accessor-class-perl libio-socket-ssl-perl libnet-ssleay-perl libcrypt-ssleay-perl
-
-# Php dependencies
-sudo apt-get install -qq php5 php5-dev php5-cli php-pear re2c
-
-# GlibC dependencies
-sudo apt-get install -qq libglib2.0-dev
-
-# Erlang dependencies
-sudo apt-get install -qq erlang-base erlang-eunit erlang-dev erlang-tools rebar
-
-# GO dependencies
-echo "golang-go golang-go/dashboard boolean false" | debconf-set-selections
-sudo apt-get -y install -qq golang golang-go
-
-# Haskell dependencies
-sudo add-apt-repository -y ppa:hvr/ghc
-sudo apt-get update
-sudo apt-get install cabal-install-1.20 ghc-$GHCVER
-
-# Lua dependencies
-sudo apt-get install -qq lua5.2 lua5.2-dev
-
-# Node.js dependencies
-sudo apt-get install -qq nodejs nodejs-dev npm
-sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10
-
-# CSharp
-sudo apt-get install -qq mono-gmcs mono-devel libmono-system-web2.0-cil
-sudo apt-get install -qq mingw32 mingw32-binutils mingw32-runtime nsis
diff --git a/build/veralign.sh b/build/veralign.sh
new file mode 100755
index 0000000..56c436a
--- /dev/null
+++ b/build/veralign.sh
@@ -0,0 +1,318 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+
+#
+# The veralign script sets the appropriate versions in all of
+# the package configuration files for all of the supported
+# languages. It is used to prepare a release or move master
+# forward to the next anticipated version.
+#
+# USAGE
+# -----------------------------------------------------------
+# usage: veralign.sh <oldVersion> <newVersion>
+#
+# EXAMPLE
+# -----------------------------------------------------------
+# $ ./veralign.sh 0.12.0 1.0.0
+# $ ./veralign.sh 1.0.0 1.1.0
+#
+# IMPORTANT USAGE NOTE
+# -----------------------------------------------------------
+# Define the environment variable DRYRUN to have the script
+# print out all matches to the oldVersion hilighted so that
+# you can verify it will change the right things.
+#
+
+declare -A FILES
+
+# These files require a manual touch:
+FILES[CHANGES.md]=manual
+FILES[debian/changelog]=manual
+FILES[doap.rdf]=manual
+
+# These files can be updated automatically:
+FILES[ApacheThrift.nuspec]=simpleReplace
+FILES[CMakeLists.txt]=simpleReplace
+FILES[Thrift.podspec]=simpleReplace
+FILES[appveyor.yml]=simpleReplace
+FILES[bower.json]=jsonReplace
+FILES[configure.ac]=configureReplace
+FILES[contrib/thrift.spec]=simpleReplace
+FILES[doc/specs/idl.md]=simpleReplace
+FILES[lib/as3/gradle.properties]=simpleReplace
+FILES[lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs]=simpleReplace
+FILES[lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj]=simpleReplace
+FILES[lib/csharp/src/Properties/AssemblyInfo.cs]=simpleReplace
+FILES[lib/csharp/src/Thrift.csproj]=simpleReplace
+FILES[lib/csharp/test/Multiplex/Client/MultiplexClient.csproj]=simpleReplace
+FILES[lib/csharp/test/Multiplex/Client/Properties/AssemblyInfo.cs]=simpleReplace
+FILES[lib/csharp/test/Multiplex/Server/MultiplexServer.csproj]=simpleReplace
+FILES[lib/csharp/test/Multiplex/Server/Properties/AssemblyInfo.cs]=simpleReplace
+FILES[lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs]=simpleReplace
+FILES[lib/d/src/thrift/base.d]=simpleReplace
+FILES[lib/dart/pubspec.yaml]=pubspecReplace
+FILES[lib/delphi/src/Thrift.pas]=simpleReplace
+FILES[lib/erl/src/thrift.app.src]=simpleReplace
+FILES[lib/haxe/haxelib.json]=simpleReplace
+FILES[lib/hs/thrift.cabal]=simpleReplace
+FILES[lib/java/gradle.properties]=simpleReplace
+FILES[lib/js/package.json]=jsonReplace
+FILES[lib/js/src/thrift.js]=simpleReplace
+FILES[lib/lua/Thrift.lua]=simpleReplace
+FILES[lib/netcore/Thrift/Properties/AssemblyInfo.cs]=simpleReplace
+FILES[lib/netcore/Thrift/Transports/Client/THttpClientTransport.cs]=simpleReplace
+FILES[lib/netstd/Thrift/Properties/AssemblyInfo.cs]=simpleReplace
+FILES[lib/netstd/Thrift/Transports/Client/THttpClientTransport.cs]=simpleReplace
+FILES[lib/ocaml/_oasis]=simpleReplace
+FILES[lib/perl/lib/Thrift.pm]=simpleReplace
+FILES[lib/py/setup.py]=simpleReplace
+FILES[lib/rb/thrift.gemspec]=simpleReplace
+FILES[lib/rs/Cargo.toml]=simpleReplace
+FILES[lib/st/package.xml]=simpleReplace
+FILES[lib/swift/Sources/Thrift.swift]=simpleReplace
+FILES[lib/swift/Tests/ThriftTests/ThriftTests.swift]=simpleReplace
+FILES[lib/ts/package.json]=jsonReplace
+FILES[package.json]=jsonReplace
+FILES[sonar-project.properties]=simpleReplace
+FILES[test/csharp/Properties/AssemblyInfo.cs]=simpleReplace
+FILES[test/csharp/ThriftTest.csproj]=simpleReplace
+FILES[test/dart/test_client/pubspec.yaml]=pubspecReplace
+FILES[test/erl/src/thrift_test.app.src]=simpleReplace
+FILES[tutorial/csharp/CsharpClient/Properties/AssemblyInfo.cs]=simpleReplace
+FILES[tutorial/csharp/CsharpServer/Properties/AssemblyInfo.cs]=simpleReplace
+FILES[tutorial/dart/client/pubspec.yaml]=pubspecReplace
+FILES[tutorial/dart/console_client/pubspec.yaml]=pubspecReplace
+FILES[tutorial/dart/server/pubspec.yaml]=pubspecReplace
+FILES[tutorial/delphi/DelphiClient/DelphiClient.dproj]=simpleReplace
+FILES[tutorial/delphi/DelphiServer/DelphiServer.dproj]=simpleReplace
+FILES[tutorial/hs/ThriftTutorial.cabal]=simpleReplace
+FILES[tutorial/ocaml/_oasis]=simpleReplace
+
+if [ ! -f "CHANGES.md" ]; then
+ >&2 echo "error: run veralign.sh while in the thrift root directory"
+ exit 1
+fi
+
+if [ $# -ne 2 ]; then
+ >&2 echo "usage: veralign.sh <oldVersion> <newVersion>"
+ exit 1
+fi
+
+jq --version 1>/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+ >&2 echo "error: the 'jq' package is not installed"
+ exit 1
+fi
+
+#
+# validateVersion: check that a version matches the major.minor.patch
+# format which is the lowest common denominator supported by all
+# project systems.
+# \param $1 the version
+# \returns 0 if the version is compliant
+#
+function validateVersion
+{
+ local result
+ local valid
+ valid=$(echo "$1" | sed '/^[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+$/!{q22}')
+ result=$?
+ if [ $result -eq 22 ]; then
+ >&2 echo "error: version '$1' does not conform to the required major.minor.patch format"
+ return ${result}
+ fi
+}
+
+OLDVERSION=$1
+NEWVERSION=$2
+validateVersion "${OLDVERSION}" || exit $?
+validateVersion "${NEWVERSION}" || exit $?
+
+#
+# escapeVersion: escape the version for use as a sed search
+# \param $1 the version to escape
+# \output the escaped string
+# \returns 0
+# \example VERSEARCH=$(escapeVersion "[1.0.0]"); echo $VERSEARCH; => "\[1\.0\.0\]"
+#
+function escapeVersion
+{
+ echo "$(echo $1 | sed 's/\./\\./g' | sed 's/\[/\\\[/g' | sed 's/\]/\\\]/g')"
+}
+
+# Set up verbose hilighting if running interactive
+if [ "$(tput colors)" -ne 0 ]; then
+ reverse=$(tput rev)
+ red=$(tput setaf 1)
+ green=$(tput setaf 2)
+ yellow=$(tput setaf 3)
+ normal=$(tput sgr0)
+fi
+
+declare -A MANUAL
+
+#
+# manual: note that update of said file is manual
+# \param $1 filename to do replacements on
+# \returns 0
+#
+function manual
+{
+ MANUAL["$1"]=""
+ return 0
+}
+
+#
+# configureReplace: replace the AC_INIT field in configure.ac
+# \param $1 filename to do replacements on
+# \returns 0 on success
+#
+
+function configureReplace
+{
+ replace "$1" "[thrift], [${OLDVERSION}]" "[thrift], [${NEWVERSION}]"
+}
+
+#
+# jsonReplace: replace a specific version field in a JSON file
+# must be a top level "version" field in the json structure
+# \param $1 filename to do replacements on
+# \returns 0 on success
+#
+
+function jsonReplace
+{
+ local result
+ local output
+ if [ ! -z "$DRYRUN" ]; then
+ output=$(jq -e ".version" "$1")
+ else
+ output=$(jq -e ".version = \"${NEWVERSION}\"" "$1" > tmp.$$.json && mv tmp.$$.json "$1")
+ fi
+ result=$?
+ if [ $? -ne 0 ]; then
+ printf "%-60s | %5d | ${red}ERROR${normal}: version tag not found" "$1" "$count"
+ echo
+ return 1
+ elif [ ! -z "$DRYRUN" ]; then
+ output=${output%\"}
+ output=${output#\"}
+ printf "%-60s | %5d | MATCHES: version: \"${reverse}${green}${output}${normal}\"" "$1" 1
+ echo
+ return 0
+ fi
+ printf "%-60s | %5d | ${green}OK${normal}" "$1" 1
+ echo
+ return 0
+}
+
+#
+# pubspecReplace: replace a specific version field in a YAML file
+# must be a top level "version" field in the yaml structure
+# did not find a package that preserves comments so this is
+# somewhat brain-dead, but it gets the job done
+# \param $1 filename to do replacements on
+# \returns 0 on success
+#
+
+function pubspecReplace
+{
+ replace "$1" "version: ${OLDVERSION}" "version: ${NEWVERSION}"
+}
+
+#
+# replace: replace occurrences of one string with another
+# the file specified must contain the old string at least once
+# in order to be successful.
+# \param $1 filename to do replacements on
+# \param $2 the "old" string to be replaced
+# \param $3 the "new" striing to replace it with
+# \returns 0 on success
+#
+function replace
+{
+ local result
+ local output
+ local oldString="$2"
+ local newString="$3"
+ local oldRegex=$(escapeVersion "${oldString}")
+ local count=$(grep -Ec "${oldRegex}" "$1")
+ local verbose
+ if [ $count -eq 0 ]; then
+ printf "%-60s | %5d | ${red}NOT FOUND${normal}: ${oldString}" "$1" 0
+ echo
+ return 1
+ elif [ ! -z "$DRYRUN" ]; then
+ printf "%-60s | %5d | MATCHES:" "$1" "$count"
+ echo
+ while read -r line; do
+ echo " > $(echo "$line" | sed "s/${oldRegex}/${reverse}${green}${oldString}${normal}/g")"
+ done < <(grep -E "${oldRegex}" "$1")
+ return 0
+ fi
+ output=$(sed -i "s/${oldRegex}/${newString}/g" "$1")
+ result=$?
+ if [ $result -ne 0 ]; then
+ printf "%-60s | %5d | ${red}ERROR${normal}: %s" "$1" "$count" "$output"
+ echo
+ return 1
+ fi
+ printf "%-60s | %5d | ${green}OK${normal}" "$1" "$count"
+ echo
+ return 0
+}
+
+#
+# simpleReplace: replace occurrences of ${OLDVERSION} with ${NEWVERSION}
+# the file specified must contain OLDVERSION at least once
+# in order to be successful.
+# \param $1 filename to do replacements on
+# \param $2 the "old" string to be replaced
+# \param $3 the "new" striing to replace it with
+# \returns 0 on success
+#
+function simpleReplace
+{
+ replace "$1" "${OLDVERSION}" "${NEWVERSION}"
+}
+
+echo ""
+echo "Apache Thrift Version Alignment Tool"
+echo "------------------------------------"
+echo ""
+echo "Previous Version: ${OLDVERSION}"
+echo " New Version: ${NEWVERSION}"
+echo ""
+echo "-------------------------------------------------------------+-------+----------------------"
+echo "Filename | Count | Status "
+echo "-------------------------------------------------------------+-------+----------------------"
+
+for file in $(echo "${!FILES[@]}" | sort); do
+ ${FILES[$file]} $file || exit $?
+done
+
+echo
+echo "Files that must be modified manually:"
+echo
+for manu in $(echo "${!MANUAL[@]}" | sort); do
+ echo " > ${yellow}${manu}${normal}"
+done
+
+exit 0
diff --git a/build/wincpp/README.md b/build/wincpp/README.md
deleted file mode 100644
index a231780..0000000
--- a/build/wincpp/README.md
+++ /dev/null
@@ -1,219 +0,0 @@
-<!---
-Licensed 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.
--->
-
-# Building thrift on Windows (Native)
-
-Thrift uses cmake to make it easier to build the project on multiple platforms, however to build a fully functional and production ready thrift on Windows requires a number of third party libraries to be obtained or built. Once third party libraries are ready, the right combination of options must be passed to cmake in order to generate the correct environment.
-
-## Summary
-
-These instructions will help you build thrift for windows using Visual
-Studio 2010 or later. The contributed batch files will help you build
-the third party libraries needed for complete thrift functionality as
-well as thrift itself.
-
-These instructions follow a directory layout that looks like the following:
-
- workspace\
- build\ - this is where the out-of-tree thrift cmake builds are generated
- dist\ - this is where the thrift build results end up
- thirdparty\ - this is where all third party binaries and libraries live
- build\ - this is where all third party out-of-tree builds are generated
- (except for openssl, which only builds in-tree)
- dist\ - this is where all third party distributions end up
- src\ - this is where all third party source projects live
- scripts\ - batch files used to set environment variables for builds
- thrift\ - this is where the thrift source project lives
-
-Create a "workspace" directory somewhere on your system and then copy the contents of this
-directory to there, then clone or unpack thrift into `workspace\thrift`.
-
-## Third Party Libraries
-
-Batch scripts are provided to build some third party libraries. You must download them and place them into the directory noted for each. You can use different versions if you prefer; these instructions were made with the versions listed.
-
-> TIP: To modify the versions used in the batch scripts, look in scripts\tpversions.bat.
-
-Build them in the order listed to satisfy their dependencies.
-
-### winflexbison
-
- source: web site
- location: https://sourceforge.net/projects/winflexbison/files/win_flex_bison-latest.zip/download
- version: "latest"
- directory: workspace\thirdparty\dist\winflexbison
-
-This package is required to build the compiler. This third party package does not need to be built as it is a binary distribution of the "bison" and "flex" tools normally found on Unix boxes.
-
-> TIP: If you are only interested in building the compiler, you can skip the remaining third party libraries.
-
-### zlib
-
- source: web site
- location: http://zlib.net/
- version: 1.2.9
- directory: workspace\thirdparty\src\zlib-1.2.9
-
-To build, open the appropriate Visual Studio command prompt and then run
-the build-zlib.bat script in thirdparty\src.
-
-### openssl
-
- source: web site
- location: https://www.openssl.org/
- version: 1.1.0c
- directory: workspace\thirdparty\src\openssl-1.1.0c
- depends-on: zlib
-
-If you are using openssl-1.1.0 or later, they changed static builds to use Microsoft Static RTL for release builds. zlib by default uses a dynamic runtime, as does libevent. Edit the file Configurations/10-main.conf and replace the section contents for "VC-noCE-common" with what appears below to make openssl build with dynamic runtime instead:
-
- "VC-noCE-common" => {
- inherit_from => [ "VC-common" ],
- template => 1,
- cflags => add(picker(default => "-DUNICODE -D_UNICODE",
- debug => "/MDd /Od -DDEBUG -D_DEBUG",
- release => "/MD /O2"
- )),
- bin_cflags => add(picker(debug => "/MDd",
- release => "/MD",
- )),
- bin_lflags => add("/subsystem:console /opt:ref"),
- ex_libs => add(sub {
- my @ex_libs = ();
- push @ex_libs, 'ws2_32.lib' unless $disabled{sock};
- push @ex_libs, 'gdi32.lib advapi32.lib crypt32.lib user32.lib';
- return join(" ", @ex_libs);
- }),
- },
-
-To build, open the appropriate Visual Studio command prompt and then run
-the build-openssl.bat script in thirdparty\src.
-
-### libevent
-
- source: git
- location: https://github.com/nmathewson/Libevent.git
- use: commit 3821cca1a637f4da4099c9343e7326da00f6981c or later
- date: Fri Dec 23 16:19:35 2016 +0800 or later
- version: corresponds to 2.1.7rc + patches
- directory: workspace\thirdparty\src\libevent-2.1.7rc2
- depends-on: openssl, zlib
-
-To build, open the appropriate Visual Studio command prompt and then run
-the build-libevent.bat script in thirdparty\src.
-
-### msinttypes
-
- source: web site
- location: https://code.google.com/archive/p/msinttypes/downloads
- version: 26
- directory: workspace\thirdparty\dist\msinttypes
-
-> TIP: This is only necessary for Visual Studio 2010, which did not include an <inttypes.h> header.
-
-This third party package does not need to be built as it is a distribution of header files.
-
-### boost
-
- source: web site
- location: http://boost.teeks99.com/
- version: 1_62_0
- directory: workspace\thirdparty\dist\boost_1_62_0
-
-The pre-built binary versions of boost come in self-unpacking executables. Run each of the ones you are interested in and point them at the same thirdparty dist directory.
-
-## Building a Production thrift Compiler
-
-### Prerequisites
-
-* CMake-2.8.12.2 or later
-* Visual Studio 2010 or later
-* thrift source placed into workspace\thrift
-* winflexbison placed into workspace\thirdparty\dist
-
-### Instructions
-
-By following these instructions you will end up with a release mode thrift compiler that is suitable for distribution as it has no external dependencies.
-
-1. Open the appropriate Visual Studio Command Prompt.
-2. `cd workspace`
-3. `build-thrift-compiler.bat`
-
-The batch file uses CMake to generate an out-of-tree build directory in `workspace\build` and then builds the compiler. The resulting `thrift.exe` program is placed into `workspace\dist` in a path that depends on your compiler version and platform. For example, if you use a Visual Studio 2010 x64 Command Prompt, the compiler will be placed into `workspace\dist\thrift-compiler-dev\vc100\x64\Release\thrift.exe`
-
-#### Details
-
-This section is for those who are curious about the CMake options used in the build process.
-
-CMake takes the source tree as the first argument and uses the remaining arguments for configuration. The batch file `build-thrift-compiler` essentially performs the following commands:
-
- C:\> CD workspace\build
- C:\workspace\build> "C:\Program Files\CMake\bin\cmake.exe" ..\thrift
- -DBISON_EXECUTABLE=..\thirdparty\dist\winflexbison\win_bison.exe
- -DCMAKE_BUILD_TYPE=Release
- -DFLEX_EXECUTABLE=..\thirdparty\dist\winflexbison\win_flex.exe
- -DWITH_MT=ON
- -DWITH_SHARED_LIB=OFF
- -G"NMake Makefiles"
- C:\workspace\build> NMAKE /FMakefile thrift-compiler
-
-WITH_MT controls the dynamic or static runtime library selection. To build a production compiler, the thrift project recommends using the static runtime library to make the executable portable. The batch file sets this.
-
-You can build a Visual Studio project file by following the example but substituting a different generator for the "-G" option. Run `cmake.exe --help` for a list of generators. Typically, this is one of the following on Windows (omit "Win64" to build 32-bit instead):
-
-* "Visual Studio 10 2010 Win64"
-* "Visual Studio 11 2012 Win64"
-* "Visual Studio 12 2013 Win64"
-* "Visual Studio 14 2015 Win64"
-* "Visual Studio 15 2017 Win64"
-
-For example you can build using a Visual Studio solution file on the command line by doing:
-
- C:\> CD workspace\build
- C:\workspace\build> "C:\Program Files\CMake\bin\cmake.exe" ..\thrift
- -DBISON_EXECUTABLE=..\thirdparty\dist\winflexbison\win_bison.exe
- -DCMAKE_BUILD_TYPE=Release
- -DFLEX_EXECUTABLE=..\thirdparty\dist\winflexbison\win_flex.exe
- -DWITH_MT=ON
- -DWITH_SHARED_LIB=OFF
- -G"Visual Studio 14 2015 Win64"
- C:\workspace\build> MSBUILD "Apache Thrift.sln" /p:Configuration=Release /p:Platform=x64 /t:thrift-compiler
-
-You can also double-click on the solution file to bring it up in Visual Studio and build or debug interactively from there.
-
-## Building the thrift C++ Run-Time Library
-
-These instructions are similar to the compiler build however there are additional dependencies on third party libraries to build a feature-complete runtime. The resulting static link library for thrift uses a dynamic Microsoft runtime.
-
-1. Open the desired Visual Studio Command Prompt.
-2. `cd workspace`
-3. `build-thrift.bat`
-
-Thrift depends on boost, libevent, openssl, and zlib in order to build with all server and transport types. To use later versions of boost like 1.62 you will need a recent version of cmake (at least 3.7).
-
-The build-thrift script has options to build debug or release and to optionally disable any of the generation (cmake), build, or test phases. By default, the batch file will generate an out-of-tree build directory inside `workspace\build`, then perform a release build, then run the unit tests. The batch file accepts some option flags to control its behavior:
-
- :: Flags you can use to change this behavior:
- ::
- :: /DEBUG - if building, perform a debug build instead
- :: /NOGENERATE - skip cmake generation - useful if you
- :: have already generated a solution and just
- :: want to build
- :: /NOBUILD - skip cmake build - useful if you just
- :: want to generate a solution
- :: /NOTEST - skip ctest execution
-
-For example if you want to generate the cmake environment without building or running tests:
-
- C:\workspace> build-thrift.bat /NOBUILD /NOTEST
diff --git a/build/wincpp/build-thrift-compiler.bat b/build/wincpp/build-thrift-compiler.bat
deleted file mode 100644
index b6b42a8..0000000
--- a/build/wincpp/build-thrift-compiler.bat
+++ /dev/null
@@ -1,79 +0,0 @@
-::
-:: Licensed 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.
-::
-
-::
-:: Produces a production thrift compiler suitable for redistribution.
-:: The compiler is linked to runtime statically for maximum portability.
-:: Assumes the thirdparty files for "winflexbison" have been placed
-:: according to the README.md instructions.
-::
-:: Open a Visual Studio Command Prompt of your choosing and then
-:: run this script.
-
-@ECHO OFF
-SETLOCAL EnableDelayedExpansion
-
-IF NOT DEFINED PACKAGE_NAME SET PACKAGE_NAME=thrift
-IF NOT DEFINED PACKAGE_VERSION SET PACKAGE_VERSION=dev
-IF NOT DEFINED SOURCE_DIR SET SOURCEDIR=%~dp0%PACKAGE_NAME%
-IF NOT DEFINED WIN3P_ROOT SET WIN3P_ROOT=%~dp0thirdparty
-
-:: Set COMPILER to (vc100 - vc140) depending on the current environment
-CALL scripts\cl_setcompiler.bat || EXIT /B
-
-:: Set ARCH to either win32 or x64 depending on the current environment
-CALL scripts\cl_setarch.bat || EXIT /B
-
-:: Set GENERATOR for CMake depending on the current environment
-CALL scripts\cl_setgenerator.bat || EXIT /B
-
-IF NOT DEFINED BUILDTYPE (
- SET BUILDTYPE=Release
-)
-
- SET BUILDDIR=%~dp0build\%PACKAGE_NAME%-compiler\%PACKAGE_VERSION%\%COMPILER%\
- SET OUTDIR=%~dp0dist\%PACKAGE_NAME%-compiler-%PACKAGE_VERSION%\%COMPILER%\%ARCH%\%BUILDTYPE%\
- SET BOOST_LIBDIR=lib%ARCH:~-2,2%-msvc-%COMPILER:~-3,2%.0
- IF "%BUILDTYPE%" == "Debug" (SET ZLIB_STATIC_SUFFIX=d)
-
- ECHO/
- ECHO =========================================================================
- ECHO Configuration: %PACKAGE_NAME% %PACKAGE_VERSION% %COMPILER%:%ARCH%:%BUILDTYPE% "%GENERATOR%"
-IF DEFINED COMPILERONLY (
- ECHO COMPILER ONLY
-)
- ECHO Build Directory: %BUILDDIR%
- ECHO Install Directory: %OUTDIR%
- ECHO Source Directory: %SOURCEDIR%
- ECHO =========================================================================
- ECHO/
-
- MKDIR "%BUILDDIR%"
- CD "%BUILDDIR%" || EXIT /B
-
- CMAKE.EXE %~dp0thrift ^
- -G"%GENERATOR%" ^
- -DBISON_EXECUTABLE=%WIN3P_ROOT%\dist\winflexbison\win_bison.exe ^
- -DCMAKE_BUILD_TYPE=%BUILDTYPE% ^
- -DFLEX_EXECUTABLE=%WIN3P_ROOT%\dist\winflexbison\win_flex.exe ^
- -DWITH_MT=ON ^
- -DWITH_SHARED_LIB=OFF || EXIT /B
-
- CD %BUILDDIR%
-
- CMAKE.EXE --build . --config %BUILDTYPE% --target thrift-compiler || EXIT /B
- XCOPY /F /Y %BUILDDIR%\bin\%BUILDTYPE%\thrift.exe %OUTDIR%
-
-ENDLOCAL
-EXIT /B
diff --git a/build/wincpp/build-thrift.bat b/build/wincpp/build-thrift.bat
deleted file mode 100644
index ba3e476..0000000
--- a/build/wincpp/build-thrift.bat
+++ /dev/null
@@ -1,164 +0,0 @@
-::
-:: Licensed 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.
-::
-
-::
-:: Generates a Visual Studio solution for thrift and then builds it.
-:: Assumes third party libraries have been built or placed already.
-::
-:: Open a Visual Studio Command Prompt of your choosing and then
-:: run this script.
-::
-:: Normally the script will run cmake to generate a solution, then
-:: perform a build, then run tests on the complete thrift library
-:: in release mode.
-::
-:: Flags you can use to change this behavior:
-::
-:: /DEBUG - debug instead of release
-:: /IDE - launch Visual Studio with a path set
-:: up correctly to run tests instead of
-:: performing any other actions, i.e.
-:: implies setting the next three flags
-:: /NOGENERATE - skip cmake generation - useful if you
-:: have already generated a solution and just
-:: want to build
-:: /NOBUILD - skip cmake build - useful if you just
-:: want to generate a solution
-:: /NOTEST - skip ctest execution
-::
-
-@ECHO OFF
-SETLOCAL EnableDelayedExpansion
-
-:: Sets variables for third party versions used in build
-CALL scripts\tpversions.bat || EXIT /B
-
-IF NOT DEFINED PACKAGE_NAME SET PACKAGE_NAME=thrift
-IF NOT DEFINED PACKAGE_VERSION SET PACKAGE_VERSION=dev
-IF NOT DEFINED SOURCE_DIR SET SOURCEDIR=%~dp0%PACKAGE_NAME%
-IF NOT DEFINED WIN3P_ROOT SET WIN3P_ROOT=%~dp0thirdparty
-
-:: Set COMPILER to (vc100 - vc140) depending on the current environment
-CALL scripts\cl_setcompiler.bat || EXIT /B
-
-:: Set ARCH to either win32 or x64 depending on the current environment
-CALL scripts\cl_setarch.bat || EXIT /B
-
-:: Set GENERATOR for CMake depending on the current environment
-CALL scripts\cl_setgenerator.bat || EXIT /B
-
-:: Defaults
-
-IF NOT DEFINED BUILDTYPE SET BUILDTYPE=Release
-SET OPT_IDE=0
-SET OPT_BUILD=1
-SET OPT_GENERATE=1
-SET OPT_TEST=1
-
-:: Apply Flags
-
-IF /I "%1" == "/DEBUG" SET BUILDTYPE=Debug
-IF /I "%2" == "/DEBUG" SET BUILDTYPE=Debug
-IF /I "%3" == "/DEBUG" SET BUILDTYPE=Debug
-IF /I "%1" == "/IDE" SET OPT_IDE=1
-IF /I "%2" == "/IDE" SET OPT_IDE=1
-IF /I "%3" == "/IDE" SET OPT_IDE=1
-IF /I "%1" == "/NOBUILD" SET OPT_BUILD=0
-IF /I "%2" == "/NOBUILD" SET OPT_BUILD=0
-IF /I "%3" == "/NOBUILD" SET OPT_BUILD=0
-IF /I "%1" == "/NOGENERATE" SET OPT_GENERATE=0
-IF /I "%2" == "/NOGENERATE" SET OPT_GENERATE=0
-IF /I "%3" == "/NOGENERATE" SET OPT_GENERATE=0
-IF /I "%1" == "/NOTEST" SET OPT_TEST=0
-IF /I "%2" == "/NOTEST" SET OPT_TEST=0
-IF /I "%3" == "/NOTEST" SET OPT_TEST=0
-
-IF %OPT_IDE% == 1 (
- SET OPT_GENERATE=0
- SET OPT_BUILD=0
- SET OPT_TEST=0
-)
-
- SET BUILDDIR=%~dp0build\%PACKAGE_NAME%\%PACKAGE_VERSION%\%COMPILER%\%ARCH%\
- SET OUTDIR=%~dp0dist\%PACKAGE_NAME%-%PACKAGE_VERSION%\%COMPILER%\%ARCH%\%BUILDTYPE%\
- SET BOOST_LIBDIR=lib%ARCH:~-2,2%-msvc-%COMPILER:~-3,2%.0
- IF "%BUILDTYPE%" == "Debug" (SET ZLIB_STATIC_SUFFIX=d)
-
- ECHO/
- ECHO =========================================================================
- ECHO Configuration: %PACKAGE_NAME% %PACKAGE_VERSION% %COMPILER%:%ARCH%:%BUILDTYPE% "%GENERATOR%"
-IF DEFINED COMPILERONLY (
- ECHO COMPILER ONLY
-)
- ECHO Build Directory: %BUILDDIR%
- ECHO Install Directory: %OUTDIR%
- ECHO Source Directory: %SOURCEDIR%
- ECHO =========================================================================
- ECHO/
-
-IF %OPT_IDE% == 1 (
-
- CALL :SETRUNPATH || EXIT /B
- CALL DEVENV "!BUILDDIR!Apache Thrift.sln" || EXIT /B
- EXIT /B
-
-)
-
- MKDIR "%BUILDDIR%"
- CD "%BUILDDIR%" || EXIT /B
-
-IF %OPT_GENERATE% == 1 (
-
- CMAKE.EXE %~dp0thrift ^
- -G"%GENERATOR%" ^
- -DBISON_EXECUTABLE=%WIN3P_ROOT%\dist\winflexbison\win_bison.exe ^
- -DBOOST_ROOT=%WIN3P_ROOT%\dist\boost_%TP_BOOST_VERSION% ^
- -DBOOST_LIBRARYDIR=%WIN3P_ROOT%\dist\boost_%TP_BOOST_VERSION%\%BOOST_LIBDIR% ^
- -DCMAKE_INSTALL_PREFIX=%OUTDIR% ^
- -DCMAKE_BUILD_TYPE=%BUILDTYPE% ^
- -DFLEX_EXECUTABLE=%WIN3P_ROOT%\dist\winflexbison\win_flex.exe ^
- -DINTTYPES_ROOT=%WIN3P_ROOT%\dist\msinttypes ^
- -DLIBEVENT_ROOT=%WIN3P_ROOT%\dist\libevent-%TP_LIBEVENT_VERSION%\%COMPILER%\%ARCH%\%BUILDTYPE% ^
- -DOPENSSL_ROOT_DIR=%WIN3P_ROOT%\dist\openssl-%TP_OPENSSL_VERSION%\%COMPILER%\%ARCH%\%BUILDTYPE%\dynamic ^
- -DOPENSSL_USE_STATIC_LIBS=OFF ^
- -DZLIB_LIBRARY=%WIN3P_ROOT%\dist\zlib-%TP_ZLIB_VERSION%\%COMPILER%\%ARCH%\lib\zlib%ZLIB_LIB_SUFFIX%.lib ^
- -DZLIB_ROOT=%WIN3P_ROOT%\dist\zlib-%TP_ZLIB_VERSION%\%COMPILER%\%ARCH% ^
- -DWITH_BOOSTTHREADS=ON ^
- -DWITH_SHARED_LIB=OFF ^
- -DWITH_STATIC_LIB=ON || EXIT /B
-
-)
-
-IF %OPT_BUILD% == 1 (
-
- CD %BUILDDIR%
- CMAKE.EXE --build . --config %BUILDTYPE% --target INSTALL || EXIT /B
-
-)
-
-IF %OPT_TEST% == 1 (
-
- CALL :SETRUNPATH || EXIT /B
- CMAKE.EXE --build . --config %BUILDTYPE% --target RUN_TESTS || EXIT /B
-
-)
-
-:SETRUNPATH
- SET PATH=!PATH!;%WIN3P_ROOT%\dist\boost_%TP_BOOST_VERSION%\%BOOST_LIBDIR%
- SET PATH=!PATH!;%WIN3P_ROOT%\dist\openssl-%TP_OPENSSL_VERSION%\%COMPILER%\%ARCH%\%BUILDTYPE%\dynamic\bin
- SET PATH=!PATH!;%WIN3P_ROOT%\dist\zlib-%TP_ZLIB_VERSION%\%COMPILER%\%ARCH%\bin
- EXIT /B
-
-ENDLOCAL
-EXIT /B
diff --git a/build/wincpp/scripts/cl_setarch.bat b/build/wincpp/scripts/cl_setarch.bat
deleted file mode 100644
index 9570a1e..0000000
--- a/build/wincpp/scripts/cl_setarch.bat
+++ /dev/null
@@ -1,47 +0,0 @@
-::
-:: Licensed 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.
-::
-
-::
-:: Detect the architecture we're building for.
-:: Set the ARCH environment variable to one of:
-:: win32
-:: x64
-::
-:: Honors any existing ARCH environment variable
-:: setting instead of overwriting it, to allow it
-:: to be forced if needed.
-::
-:: Sets ERRORLEVEL to 0 if ARCH can be determined,
-:: to 1 if it cannot.
-::
-
-IF DEFINED ARCH (
- ECHO [warn ] using existing environment variable ARCH
- EXIT /B 0
-)
-
-CALL :CHECK x64
-IF %ERRORLEVEL% == 0 (SET ARCH=x64) ELSE (SET ARCH=win32)
-
-IF NOT DEFINED ARCH (
- ECHO [error] unable to determine the target architecture
- EXIT /B 1
-)
-
-ECHO [info ] detected target architecture %ARCH%
-EXIT /B 0
-
-:CHECK
-cl /? 2>&1 | findstr /C:" for %1%" > nul
-EXIT /B %ERRORLEVEL%
diff --git a/build/wincpp/scripts/cl_setcompiler.bat b/build/wincpp/scripts/cl_setcompiler.bat
deleted file mode 100644
index 8405d76..0000000
--- a/build/wincpp/scripts/cl_setcompiler.bat
+++ /dev/null
@@ -1,58 +0,0 @@
-::
-:: Licensed 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.
-::
-
-::
-:: Detect the compiler edition we're building in.
-:: Set the COMPILER environment variable to one of:
-:: vc100 = Visual Studio 2010
-:: vc110 = Visual Studio 2012
-:: vc120 = Visual Studio 2013
-:: vc140 = Visual Studio 2015
-:: vc150 = Visual Studio 2017
-::
-:: Honors any existing COMPILER environment variable
-:: setting instead of overwriting it, to allow it
-:: to be forced if needed.
-::
-:: Sets ERRORLEVEL to 0 if COMPILER can be determined,
-:: to 1 if it cannot.
-::
-
-IF DEFINED COMPILER (
- ECHO [warn ] using existing environment variable COMPILER
- EXIT /B 0
-)
-
-CALL :CHECK 16
-IF %ERRORLEVEL% == 0 (IF NOT DEFINED COMPILER SET COMPILER=vc100)
-CALL :CHECK 17
-IF %ERRORLEVEL% == 0 (IF NOT DEFINED COMPILER SET COMPILER=vc110)
-CALL :CHECK 18
-IF %ERRORLEVEL% == 0 (IF NOT DEFINED COMPILER SET COMPILER=vc120)
-CALL :CHECK 19.00
-IF %ERRORLEVEL% == 0 (IF NOT DEFINED COMPILER SET COMPILER=vc140)
-CALL :CHECK 19.10
-IF %ERRORLEVEL% == 0 (IF NOT DEFINED COMPILER SET COMPILER=vc150)
-
-IF NOT DEFINED COMPILER (
- ECHO [error] unable to determine the compiler edition
- EXIT /B 1
-)
-
-ECHO [info ] detected compiler edition %COMPILER%
-EXIT /B 0
-
-:CHECK
-cl /? 2>&1 | findstr /C:"Version %1%." > nul
-EXIT /B %ERRORLEVEL%
diff --git a/build/wincpp/scripts/cl_setgenerator.bat b/build/wincpp/scripts/cl_setgenerator.bat
deleted file mode 100644
index bae2742..0000000
--- a/build/wincpp/scripts/cl_setgenerator.bat
+++ /dev/null
@@ -1,69 +0,0 @@
-::
-:: Licensed 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.
-::
-
-::
-:: Detect the compiler edition we're building in and then
-:: set the GENERATOR environment variable to one of:
-::
-:: Visual Studio 15 2017 [arch] = Generates Visual Studio 2017 project files.
-:: Optional [arch] can be "Win64" or "ARM".
-:: Visual Studio 14 2015 [arch] = Generates Visual Studio 2015 project files.
-:: Optional [arch] can be "Win64" or "ARM".
-:: Visual Studio 12 2013 [arch] = Generates Visual Studio 2013 project files.
-:: Optional [arch] can be "Win64" or "ARM".
-:: Visual Studio 11 2012 [arch] = Generates Visual Studio 2012 project files.
-:: Optional [arch] can be "Win64" or "ARM".
-:: Visual Studio 10 2010 [arch] = Generates Visual Studio 2010 project files.
-:: Optional [arch] can be "Win64" or "IA64".
-::
-:: Honors any existing GENERATOR environment variable
-:: setting instead of overwriting it, to allow it
-:: to be forced if needed.
-::
-:: Sets ERRORLEVEL to 0 if GENERATOR can be determined,
-:: to 1 if it cannot.
-::
-:: Requires cl_setarch.bat to have been executed or the ARCH environment
-:: variable to be set.
-::
-
-IF "%ARCH%" == "x64" (SET GENARCH= Win64)
-
-IF DEFINED GENERATOR (
- ECHO [warn ] using existing environment variable GENERATOR
- EXIT /B 0
-)
-
-CALL :CHECK 16
-IF %ERRORLEVEL% == 0 (IF NOT DEFINED GENERATOR SET GENERATOR=Visual Studio 10 2010%GENARCH%)
-CALL :CHECK 17
-IF %ERRORLEVEL% == 0 (IF NOT DEFINED GENERATOR SET GENERATOR=Visual Studio 11 2012%GENARCH%)
-CALL :CHECK 18
-IF %ERRORLEVEL% == 0 (IF NOT DEFINED GENERATOR SET GENERATOR=Visual Studio 12 2013%GENARCH%)
-CALL :CHECK 19.00
-IF %ERRORLEVEL% == 0 (IF NOT DEFINED GENERATOR SET GENERATOR=Visual Studio 14 2015%GENARCH%)
-CALL :CHECK 19.10
-IF %ERRORLEVEL% == 0 (IF NOT DEFINED GENERATOR SET GENERATOR=Visual Studio 15 2017%GENARCH%)
-
-IF NOT DEFINED GENERATOR (
- ECHO [error] unable to determine the CMake generator to use
- EXIT /B 1
-)
-
-ECHO [info ] using CMake generator %GENERATOR%
-EXIT /B 0
-
-:CHECK
-cl /? 2>&1 | findstr /C:"Version %1%." > nul
-EXIT /B %ERRORLEVEL%
diff --git a/build/wincpp/scripts/tpversions.bat b/build/wincpp/scripts/tpversions.bat
deleted file mode 100644
index d80c868..0000000
--- a/build/wincpp/scripts/tpversions.bat
+++ /dev/null
@@ -1,24 +0,0 @@
-::
-:: Licensed 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.
-::
-
-::
-:: Set the versions of third party libraries to use.
-::
-
-IF NOT DEFINED TP_BOOST_VERSION SET TP_BOOST_VERSION=1_62_0
-IF NOT DEFINED TP_LIBEVENT_VERSION SET TP_LIBEVENT_VERSION=2.1.7rc2
-IF NOT DEFINED TP_OPENSSL_VERSION SET TP_OPENSSL_VERSION=1.1.0c
-IF NOT DEFINED TP_ZLIB_VERSION SET TP_ZLIB_VERSION=1.2.9
-
-EXIT /B 0
diff --git a/build/wincpp/thirdparty/src/build-libevent.bat b/build/wincpp/thirdparty/src/build-libevent.bat
deleted file mode 100644
index 4af505c..0000000
--- a/build/wincpp/thirdparty/src/build-libevent.bat
+++ /dev/null
@@ -1,86 +0,0 @@
-::
-:: Licensed 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.
-::
-
-::
-:: Build script for libevent on windows
-:: Use libevent master from github which has cmake integration
-:: Uses the environment set up by a Visual Studio Command Prompt shortcut
-:: to target a specific architecture and compiler
-::
-:: Creates a static link library.
-:: Links against OpenSSL and zlib statically.
-::
-
-@ECHO OFF
-SETLOCAL EnableDelayedExpansion
-
-:: Sets variables for third party versions used in build
-CALL ..\..\scripts\tpversions.bat || EXIT /B
-
-:: use "build-libevent.bat /yes" to skip the question part
-IF /I "%1" == "/YES" SET NOASK=1
-
-:: Set COMPILER to (vc100 - vc140) depending on the current environment
-CALL ..\..\scripts\cl_setcompiler.bat || EXIT /B
-
-:: Set ARCH to either win32 or x64 depending on the current environment
-CALL ..\..\scripts\cl_setarch.bat || EXIT /B
-
-IF NOT DEFINED GENERATOR SET GENERATOR=NMake Makefiles
-IF NOT DEFINED PACKAGE_NAME SET PACKAGE_NAME=libevent
-IF NOT DEFINED PACKAGE_VERSION SET PACKAGE_VERSION=%TP_LIBEVENT_VERSION%
-IF NOT DEFINED SOURCEDIR SET SOURCEDIR=%~dp0%PACKAGE_NAME%-%PACKAGE_VERSION%
-IF NOT DEFINED WIN3P_ROOT SET WIN3P_ROOT=%~dp0..
-
-FOR %%X IN (
- Debug
- Release
-) DO (
- SET BUILDTYPE=%%X
- SET BUILDDIR=%WIN3P_ROOT%\build\%PACKAGE_NAME%\%PACKAGE_VERSION%\%COMPILER%\%ARCH%\!BUILDTYPE!
- SET OUTDIR=%WIN3P_ROOT%\dist\%PACKAGE_NAME%-%PACKAGE_VERSION%\%COMPILER%\%ARCH%\!BUILDTYPE!
-
- IF "!BUILDTYPE!" == "Debug" (SET ZLIB_LIB_SUFFIX=d)
-
- SET CMAKE_DEFS=^
- -DEVENT__DISABLE_SAMPLES=ON ^
- -DEVENT__DISABLE_TESTS=ON ^
- -DOPENSSL_USE_STATIC_LIBS=OFF ^
- -DOPENSSL_ROOT_DIR=%WIN3P_ROOT%\dist\openssl-%TP_OPENSSL_VERSION%\%COMPILER%\%ARCH%\!BUILDTYPE!\dynamic ^
- -DZLIB_LIBRARY=%WIN3P_ROOT%\dist\zlib-%TP_ZLIB_VERSION%\%COMPILER%\%ARCH%\lib\zlib!ZLIB_LIB_SUFFIX!.lib ^
- -DZLIB_ROOT=%WIN3P_ROOT%\dist\zlib-%TP_ZLIB_VERSION%\%COMPILER%\%ARCH%
-
- ECHO/
- ECHO =========================================================================
- ECHO Building: %PACKAGE_NAME% v%PACKAGE_VERSION% %COMPILER%:%ARCH%:!BUILDTYPE! "%GENERATOR%"
- ECHO CMake Definitions: !CMAKE_DEFS!
- ECHO Build Directory: !BUILDDIR!
- ECHO Install Directory: !OUTDIR!
- ECHO Source Directory: %SOURCEDIR%
- ECHO =========================================================================
- ECHO/
-
- IF NOT DEFINED NOASK (
- CHOICE /M "Do you want to build this configuration? " /c YN
- IF !ERRORLEVEL! NEQ 1 (EXIT /B !ERRORLEVEL!)
- )
-
- MKDIR "!BUILDDIR!"
- CD "!BUILDDIR!" || EXIT /B
-
- CMAKE.EXE -G"%GENERATOR%" -DCMAKE_INSTALL_PREFIX=!OUTDIR! -DCMAKE_BUILD_TYPE=!BUILDTYPE! !CMAKE_DEFS! "%SOURCEDIR%" || EXIT /B
- NMAKE /fMakefile install || EXIT /B
-)
-
-ENDLOCAL
diff --git a/build/wincpp/thirdparty/src/build-openssl.bat b/build/wincpp/thirdparty/src/build-openssl.bat
deleted file mode 100644
index cf270f0..0000000
--- a/build/wincpp/thirdparty/src/build-openssl.bat
+++ /dev/null
@@ -1,106 +0,0 @@
-::
-:: Licensed 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.
-::
-
-::
-:: Build script for openssl on windows
-:: openssl uses an in-tree build so you have to clean between each one
-::
-:: Uses the environment set up by a Visual Studio Command Prompt shortcut
-:: to target a specific architecture and compiler
-::
-:: If you use Lavasoft Ad-Aware, disable it for this build. It blocks the creation
-:: of any file named "clienthellotest.exe" for whatever reason, which breaks the build.
-::
-
-@ECHO OFF
-SETLOCAL EnableDelayedExpansion
-
-:: Sets variables for third party versions used in build
-CALL ..\..\scripts\tpversions.bat || EXIT /B
-
-:: use "build-openssl.bat /yes" to skip the question part
-IF /I "%1" == "/YES" SET NOASK=1
-
-IF NOT DEFINED PACKAGE_NAME SET PACKAGE_NAME=openssl
-IF NOT DEFINED PACKAGE_VERSION SET PACKAGE_VERSION=%TP_OPENSSL_VERSION%
-IF NOT DEFINED SOURCEDIR SET SOURCEDIR=%~dp0%PACKAGE_NAME%-%PACKAGE_VERSION%
-IF NOT DEFINED WIN3P_ROOT SET WIN3P_ROOT=%~dp0..
-
-:: Set COMPILER to (vc100 - vc140) depending on the current environment
-CALL ..\..\scripts\cl_setcompiler.bat || EXIT /B
-
-:: Set ARCH to either win32 or x64 depending on the current environment
-CALL ..\..\scripts\cl_setarch.bat || EXIT /B
-
-IF "%ARCH%" == "x64" (
- SET TODO=debug-VC-WIN64A VC-WIN64A
-) ELSE (
- SET TODO=debug-VC-WIN32 VC-WIN32
-)
-
-FOR %%X IN ( !TODO! ) DO (
- SET BUILDTYPE=%%X
- FOR %%Y IN (
- nt
- ntdll
- ) DO (
- SET LIBTYPE=%%Y
-
- IF "!BUILDTYPE:~0,6!" == "debug-" (
- SET OUTBUILDTYPE=debug
- SET ZLIBLIBSUFFIX=d
- ) ELSE (
- SET OUTBUILDTYPE=release
- SET ZLIBLIBSUFFIX=
- )
-
- IF "!LIBTYPE!" == "ntdll" (
- SET BUILD_OPTIONS=shared
- SET OUTLIBTYPE=dynamic
- SET ZLIBLIB=zlib!ZLIBLIBSUFFIX!
- SET ZLIBOPT=zlib-dynamic
- ) ELSE (
- SET BUILD_OPTIONS=no-shared
- SET OUTLIBTYPE=static
- SET ZLIBLIB=zlibstatic!ZLIBLIBSUFFIX!.lib
- SET ZLIBOPT=zlib
- )
-
- SET LIB=%~dp0..\dist\zlib-%TP_ZLIB_VERSION%\!COMPILER!\!ARCH!\lib;!LIB!
- SET BUILD_OPTIONS=!BUILD_OPTIONS! no-asm no-unit-test !ZLIBOPT! --openssldir=ssl --with-zlib-include=%~dp0..\dist\zlib-%TP_ZLIB_VERSION%\!COMPILER!\!ARCH!\include --with-zlib-lib=!ZLIBLIB!
- SET OUTDIR=%WIN3P_ROOT%\dist\%PACKAGE_NAME%-%PACKAGE_VERSION%\%COMPILER%\%ARCH%\!OUTBUILDTYPE!\!OUTLIBTYPE!
-
- ECHO/
- ECHO =========================================================================
- ECHO Building: %PACKAGE_NAME% %PACKAGE_VERSION% %COMPILER%:%ARCH%:!OUTBUILDTYPE!:!OUTLIBTYPE! [!BUILDTYPE!]
- ECHO Configure Options: !BUILD_OPTIONS!
- ECHO Install Directory: !OUTDIR!
- ECHO Source Directory: %SOURCEDIR%
- ECHO =========================================================================
- ECHO/
-
- IF NOT DEFINED NOASK (
- CHOICE /M "Do you want to build this configuration? " /c YN
- IF !ERRORLEVEL! NEQ 1 (EXIT /B !ERRORLEVEL!)
- )
-
- CD %SOURCEDIR% || EXIT /B
- perl Configure !BUILDTYPE! --prefix="!OUTDIR!" !BUILD_OPTIONS! || EXIT /B
- NMAKE /FMakefile install_sw || EXIT /B
- NMAKE /FMakefile clean || EXIT /B
- )
-)
-
-ENDLOCAL
-EXIT /B
diff --git a/build/wincpp/thirdparty/src/build-zlib.bat b/build/wincpp/thirdparty/src/build-zlib.bat
deleted file mode 100644
index 2427230..0000000
--- a/build/wincpp/thirdparty/src/build-zlib.bat
+++ /dev/null
@@ -1,75 +0,0 @@
-::
-:: Licensed 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.
-::
-
-::
-:: Build script for zlib on windows.
-:: Uses the environment set up by a Visual Studio Command Prompt shortcut
-:: to target a specific architecture and compiler.
-::
-
-@ECHO OFF
-SETLOCAL EnableDelayedExpansion
-
-:: Sets variables for third party versions used in build
-CALL ..\..\scripts\tpversions.bat || EXIT /B
-
-:: use "build-zlib.bat /yes" to skip the question part
-IF /I "%1" == "/YES" SET NOASK=1
-
-IF NOT DEFINED GENERATOR SET GENERATOR=NMake Makefiles
-IF NOT DEFINED PACKAGE_NAME SET PACKAGE_NAME=zlib
-IF NOT DEFINED PACKAGE_VERSION SET PACKAGE_VERSION=%TP_ZLIB_VERSION%
-IF NOT DEFINED SOURCE_DIR SET SOURCEDIR=%~dp0%PACKAGE_NAME%-%PACKAGE_VERSION%
-IF NOT DEFINED WIN3P_ROOT SET WIN3P_ROOT=%~dp0..
-
-:: Set COMPILER to (vc100 - vc140) depending on the current environment
-CALL ..\..\scripts\cl_setcompiler.bat || EXIT /B
-
-:: Set ARCH to either win32 or x64 depending on the current environment
-CALL ..\..\scripts\cl_setarch.bat || EXIT /B
-
-FOR %%X IN (
- Debug
- Release
-) DO (
- SET BUILDTYPE=%%X
- SET BUILDDIR=%WIN3P_ROOT%\build\%PACKAGE_NAME%\%PACKAGE_VERSION%\%COMPILER%\%ARCH%\!BUILDTYPE!
- SET OUTDIR=%WIN3P_ROOT%\dist\%PACKAGE_NAME%-%PACKAGE_VERSION%\%COMPILER%\%ARCH%
-
- ECHO/
- ECHO =========================================================================
- ECHO Building: %PACKAGE_NAME% v%PACKAGE_VERSION% %COMPILER%:%ARCH%:!BUILDTYPE! "%GENERATOR%"
- ECHO Build Directory: !BUILDDIR!
- ECHO Install Directory: !OUTDIR!
- ECHO Source Directory: %SOURCEDIR%
- ECHO =========================================================================
- ECHO/
-
- IF NOT DEFINED NOASK (
- CHOICE /M "Do you want to build this configuration? " /c YN
- IF !ERRORLEVEL! NEQ 1 (EXIT /B !ERRORLEVEL!)
- )
-
- MKDIR "!BUILDDIR!"
- CD "!BUILDDIR!" || EXIT /B
-
- CMAKE.EXE -G"%GENERATOR%" -DCMAKE_INSTALL_PREFIX=!OUTDIR! -DCMAKE_BUILD_TYPE=!BUILDTYPE! "%SOURCEDIR%" || EXIT /B
- NMAKE /fMakefile install || EXIT /B
-
- IF "!BUILDTYPE!" == "Debug" (
- COPY "!BUILDDIR!\zlibd.pdb" "!OUTDIR!\bin\" || EXIT /B
- )
-)
-
-ENDLOCAL
diff --git a/cleanup.sh b/cleanup.sh
deleted file mode 100755
index f110721..0000000
--- a/cleanup.sh
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/sh
-
-#
-# 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.
-#
-
-topsrcdir="`dirname $0`"
-cd "$topsrcdir"
-
-make -k clean >/dev/null 2>&1
-make -k distclean >/dev/null 2>&1
-find . -name Makefile.in -exec rm -f {} \;
-rm -rf \
-AUTHORS \
-ChangeLog \
-INSTALL \
-Makefile \
-Makefile.in \
-Makefile.orig \
-aclocal/libtool.m4 \
-aclocal/ltoptions.m4 \
-aclocal/ltsugar.m4 \
-aclocal/ltversion.m4 \
-aclocal/lt~obsolete.m4 \
-aclocal.m4 \
-autom4te.cache \
-autoscan.log \
-config.guess \
-config.h \
-config.hin \
-config.hin~ \
-config.log \
-config.status \
-config.status.lineno \
-config.sub \
-configure \
-configure.lineno \
-configure.scan \
-depcomp \
-.deps \
-install-sh \
-.libs \
-libtool \
-ltmain.sh \
-missing \
-ylwrap \
-if/gen-* \
-test/gen-* \
-lib/php/src/ext/thrift_protocol/.deps \
-lib/php/src/ext/thrift_protocol/Makefile \
-lib/php/src/ext/thrift_protocol/Makefile.fragments \
-lib/php/src/ext/thrift_protocol/Makefile.global \
-lib/php/src/ext/thrift_protocol/Makefile.objects \
-lib/php/src/ext/thrift_protocol/acinclude.m4 \
-lib/php/src/ext/thrift_protocol/aclocal.m4 \
-lib/php/src/ext/thrift_protocol/autom4te.cache \
-lib/php/src/ext/thrift_protocol/build \
-lib/php/src/ext/thrift_protocol/config.guess \
-lib/php/src/ext/thrift_protocol/config.h \
-lib/php/src/ext/thrift_protocol/config.h.in \
-lib/php/src/ext/thrift_protocol/config.log \
-lib/php/src/ext/thrift_protocol/config.nice \
-lib/php/src/ext/thrift_protocol/config.status \
-lib/php/src/ext/thrift_protocol/config.sub \
-lib/php/src/ext/thrift_protocol/configure \
-lib/php/src/ext/thrift_protocol/configure.in \
-lib/php/src/ext/thrift_protocol/include \
-lib/php/src/ext/thrift_protocol/install-sh \
-lib/php/src/ext/thrift_protocol/libtool \
-lib/php/src/ext/thrift_protocol/ltmain.sh \
-lib/php/src/ext/thrift_protocol/missing \
-lib/php/src/ext/thrift_protocol/mkinstalldirs \
-lib/php/src/ext/thrift_protocol/modules \
-lib/php/src/ext/thrift_protocol/run-tests.php
diff --git a/compiler/cpp/CMakeLists.txt b/compiler/cpp/CMakeLists.txt
index 0df790e..17dae47 100644
--- a/compiler/cpp/CMakeLists.txt
+++ b/compiler/cpp/CMakeLists.txt
@@ -16,18 +16,11 @@
# specific language governing permissions and limitations
# under the License.
#
-cmake_minimum_required(VERSION 2.8.12)
+
+cmake_minimum_required(VERSION 3.3)
+project("thrift-compiler" VERSION ${PACKAGE_VERSION})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/thrift/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/thrift/version.h)
-if(MSVC)
- # The winflexbison generator outputs some macros that conflict with the Visual Studio 2010 copy of stdint.h
- # This might be fixed in later versions of Visual Studio, but an easy solution is to include stdint.h first
- if(HAVE_STDINT_H)
- add_definitions(-D__STDC_FORMAT_MACROS)
- add_definitions(-D__STDC_LIMIT_MACROS)
- add_definitions(/FI"stdint.h")
- endif(HAVE_STDINT_H)
-endif()
find_package(FLEX REQUIRED)
find_package(BISON REQUIRED)
@@ -78,86 +71,46 @@
endmacro()
# The following compiler can be enabled or disabled
-THRIFT_ADD_COMPILER(c_glib "Enable compiler for C with Glib" ON)
-THRIFT_ADD_COMPILER(cpp "Enable compiler for C++" ON)
-THRIFT_ADD_COMPILER(java "Enable compiler for Java" ON)
THRIFT_ADD_COMPILER(as3 "Enable compiler for ActionScript 3" ON)
-THRIFT_ADD_COMPILER(dart "Enable compiler for Dart" ON)
-THRIFT_ADD_COMPILER(haxe "Enable compiler for Haxe" ON)
+THRIFT_ADD_COMPILER(c_glib "Enable compiler for C with Glib" ON)
+THRIFT_ADD_COMPILER(cl "Enable compiler for Common LISP" ON)
+THRIFT_ADD_COMPILER(cpp "Enable compiler for C++" ON)
THRIFT_ADD_COMPILER(csharp "Enable compiler for C#" ON)
-THRIFT_ADD_COMPILER(netcore "Enable compiler for .NET Core" ON)
-THRIFT_ADD_COMPILER(py "Enable compiler for Python 2.0" ON)
-THRIFT_ADD_COMPILER(rb "Enable compiler for Ruby" ON)
-THRIFT_ADD_COMPILER(perl "Enable compiler for Perl" ON)
-THRIFT_ADD_COMPILER(php "Enable compiler for PHP" ON)
+THRIFT_ADD_COMPILER(d "Enable compiler for D" ON)
+THRIFT_ADD_COMPILER(dart "Enable compiler for Dart" ON)
+THRIFT_ADD_COMPILER(delphi "Enable compiler for Delphi" ON)
THRIFT_ADD_COMPILER(erl "Enable compiler for Erlang" ON)
-THRIFT_ADD_COMPILER(cocoa "Enable compiler for Cocoa Objective-C" ON)
-THRIFT_ADD_COMPILER(swift "Enable compiler for Cocoa Swift" ON)
-THRIFT_ADD_COMPILER(st "Enable compiler for Smalltalk" ON)
-THRIFT_ADD_COMPILER(ocaml "Enable compiler for OCaml" ON)
+THRIFT_ADD_COMPILER(go "Enable compiler for Go" ON)
+THRIFT_ADD_COMPILER(gv "Enable compiler for GraphViz" ON)
+THRIFT_ADD_COMPILER(haxe "Enable compiler for Haxe" ON)
THRIFT_ADD_COMPILER(hs "Enable compiler for Haskell" ON)
-THRIFT_ADD_COMPILER(xsd "Enable compiler for XSD" ON)
THRIFT_ADD_COMPILER(html "Enable compiler for HTML Documentation" ON)
+THRIFT_ADD_COMPILER(java "Enable compiler for Java" ON)
+THRIFT_ADD_COMPILER(javame "Enable compiler for Java ME" ON)
THRIFT_ADD_COMPILER(js "Enable compiler for JavaScript" ON)
THRIFT_ADD_COMPILER(json "Enable compiler for JSON" ON)
-THRIFT_ADD_COMPILER(javame "Enable compiler for Java ME" ON)
-THRIFT_ADD_COMPILER(delphi "Enable compiler for Delphi" ON)
-THRIFT_ADD_COMPILER(go "Enable compiler for Go" ON)
-THRIFT_ADD_COMPILER(d "Enable compiler for D" ON)
THRIFT_ADD_COMPILER(lua "Enable compiler for Lua" ON)
-THRIFT_ADD_COMPILER(gv "Enable compiler for GraphViz" ON)
+THRIFT_ADD_COMPILER(netcore "Enable compiler for .NET Core" ON)
+THRIFT_ADD_COMPILER(netstd "Enable compiler for .NET Standard" ON)
+THRIFT_ADD_COMPILER(ocaml "Enable compiler for OCaml" ON)
+THRIFT_ADD_COMPILER(perl "Enable compiler for Perl" ON)
+THRIFT_ADD_COMPILER(php "Enable compiler for PHP" ON)
+THRIFT_ADD_COMPILER(py "Enable compiler for Python 2.0" ON)
+THRIFT_ADD_COMPILER(rb "Enable compiler for Ruby" ON)
THRIFT_ADD_COMPILER(rs "Enable compiler for Rust" ON)
+THRIFT_ADD_COMPILER(st "Enable compiler for Smalltalk" ON)
+THRIFT_ADD_COMPILER(swift "Enable compiler for Cocoa Swift" ON)
THRIFT_ADD_COMPILER(xml "Enable compiler for XML" ON)
+THRIFT_ADD_COMPILER(xsd "Enable compiler for XSD" ON)
# Thrift is looking for include files in the src directory
# we also add the current binary directory for generated files
include_directories(${CMAKE_CURRENT_BINARY_DIR} src)
-if(NOT DEFINED WITH_PLUGIN OR NOT ${WITH_PLUGIN})
- list(APPEND thrift-compiler_SOURCES ${compiler_core})
-endif()
+list(APPEND thrift-compiler_SOURCES ${compiler_core})
add_executable(thrift-compiler ${thrift-compiler_SOURCES})
-if(${WITH_PLUGIN})
- add_executable(thrift-bootstrap ${compiler_core}
- src/thrift/main.cc
- src/thrift/audit/t_audit.cpp
- src/thrift/generate/t_cpp_generator.cc
- )
- target_link_libraries(thrift-bootstrap parse)
-
- set(PLUGIN_GEN_SOURCES
- ${CMAKE_CURRENT_BINARY_DIR}/thrift/plugin/plugin_types.h
- ${CMAKE_CURRENT_BINARY_DIR}/thrift/plugin/plugin_types.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/thrift/plugin/plugin_constants.h
- ${CMAKE_CURRENT_BINARY_DIR}/thrift/plugin/plugin_constants.cpp
- )
-
- file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/thrift/plugin)
- add_custom_command(OUTPUT ${PLUGIN_GEN_SOURCES}
- DEPENDS thrift-bootstrap src/thrift/plugin/plugin.thrift
- COMMAND thrift-bootstrap -gen cpp
- -out ${CMAKE_CURRENT_BINARY_DIR}/thrift/plugin
- ${CMAKE_CURRENT_SOURCE_DIR}/src/thrift/plugin/plugin.thrift
- )
-
- include_directories(../../lib/cpp/src)
-
- include(ThriftMacros)
- ADD_LIBRARY_THRIFT(thriftc
- ${compiler_core}
- ${PLUGIN_GEN_SOURCES}
- src/thrift/logging.cc
- src/thrift/plugin/plugin_output.cc
- src/thrift/plugin/plugin.cc
- )
- TARGET_INCLUDE_DIRECTORIES_THRIFT(thriftc PUBLIC ${Boost_INCLUDE_DIRS})
- TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY(thriftc thrift PUBLIC)
- target_compile_definitions(thrift-compiler PUBLIC THRIFT_ENABLE_PLUGIN)
- LINK_AGAINST_THRIFT_LIBRARY(thrift-compiler thriftc)
-endif()
-
set_target_properties(thrift-compiler PROPERTIES RUNTIME_OUTPUT_DIRECTORY bin/)
set_target_properties(thrift-compiler PROPERTIES OUTPUT_NAME thrift)
@@ -165,57 +118,6 @@
install(TARGETS thrift-compiler DESTINATION bin)
-if(${WITH_PLUGIN})
- # Install the headers
- install(FILES
- "src/thrift/common.h"
- "src/thrift/globals.h"
- "src/thrift/logging.h"
- "src/thrift/main.h"
- "src/thrift/platform.h"
- "${CMAKE_BINARY_DIR}/compiler/cpp/thrift/version.h"
- DESTINATION "${INCLUDE_INSTALL_DIR}/thrift")
- install(FILES
- "src/thrift/audit/t_audit.h"
- DESTINATION "${INCLUDE_INSTALL_DIR}/thrift/audit")
- install(FILES
- "src/thrift/generate/t_generator.h"
- "src/thrift/generate/t_generator_registry.h"
- "src/thrift/generate/t_html_generator.h"
- "src/thrift/generate/t_oop_generator.h"
- DESTINATION "${INCLUDE_INSTALL_DIR}/thrift/generate")
- install(FILES
- "src/thrift/parse/t_base_type.h"
- "src/thrift/parse/t_const.h"
- "src/thrift/parse/t_const_value.h"
- "src/thrift/parse/t_container.h"
- "src/thrift/parse/t_doc.h"
- "src/thrift/parse/t_enum.h"
- "src/thrift/parse/t_enum_value.h"
- "src/thrift/parse/t_field.h"
- "src/thrift/parse/t_function.h"
- "src/thrift/parse/t_list.h"
- "src/thrift/parse/t_map.h"
- "src/thrift/parse/t_program.h"
- "src/thrift/parse/t_scope.h"
- "src/thrift/parse/t_service.h"
- "src/thrift/parse/t_set.h"
- "src/thrift/parse/t_struct.h"
- "src/thrift/parse/t_typedef.h"
- "src/thrift/parse/t_type.h"
- DESTINATION "${INCLUDE_INSTALL_DIR}/thrift/parse")
- install(FILES
- "src/thrift/plugin/plugin.h"
- "src/thrift/plugin/plugin_output.h"
- "src/thrift/plugin/type_util.h"
- DESTINATION "${INCLUDE_INSTALL_DIR}/thrift/plugin")
-if(MSVC)
- install(FILES
- "src/thrift/windows/config.h"
- DESTINATION "${INCLUDE_INSTALL_DIR}/thrift/windows")
-endif()
-endif()
-
if(BUILD_TESTING)
add_subdirectory(test)
endif()
diff --git a/compiler/cpp/Makefile.am b/compiler/cpp/Makefile.am
index 0b8ef2e..16d4d3a 100644
--- a/compiler/cpp/Makefile.am
+++ b/compiler/cpp/Makefile.am
@@ -23,12 +23,7 @@
AUTOMAKE_OPTIONS = subdir-objects
-# Note on why we have src/thrift and src/thrift/plugin directories:
-# Since Automake supports only one set of BUILT_SOURCES per file and does not allow
-# SUBDIRS built before BUILT_SOURCES, we end up separate Makefile.am for each source
-# code generation, i.e. lex-yacc and Thrift, to achieve stable parallel make.
-
-SUBDIRS = src src/thrift/plugin .
+SUBDIRS = src .
if WITH_TESTS
SUBDIRS += test
endif
@@ -37,155 +32,80 @@
thrift_OBJDIR = obj
-plugin_gen = src/thrift/plugin/plugin_types.h \
- src/thrift/plugin/plugin_types.cpp \
- src/thrift/plugin/plugin_constants.h \
- src/thrift/plugin/plugin_constants.cpp
-
-compiler_core = src/thrift/common.h \
+thrift_SOURCES = src/thrift/audit/t_audit.cpp \
+ src/thrift/audit/t_audit.h \
src/thrift/common.cc \
+ src/thrift/common.h \
src/thrift/generate/t_generator.cc \
+ src/thrift/generate/t_generator.h \
src/thrift/generate/t_generator_registry.h \
+ src/thrift/generate/t_html_generator.h \
+ src/thrift/generate/t_oop_generator.h \
src/thrift/globals.h \
- src/thrift/platform.h \
src/thrift/logging.h \
- src/thrift/parse/t_doc.h \
- src/thrift/parse/t_type.h \
+ src/thrift/main.cc \
+ src/thrift/main.h \
+ src/thrift/parse/parse.cc \
src/thrift/parse/t_base_type.h \
- src/thrift/parse/t_enum.h \
- src/thrift/parse/t_enum_value.h \
- src/thrift/parse/t_typedef.h \
- src/thrift/parse/t_typedef.cc \
- src/thrift/parse/t_container.h \
- src/thrift/parse/t_list.h \
- src/thrift/parse/t_set.h \
- src/thrift/parse/t_map.h \
- src/thrift/parse/t_struct.h \
- src/thrift/parse/t_field.h \
- src/thrift/parse/t_service.h \
- src/thrift/parse/t_function.h \
- src/thrift/parse/t_program.h \
- src/thrift/parse/t_scope.h \
src/thrift/parse/t_const.h \
src/thrift/parse/t_const_value.h \
- src/thrift/parse/parse.cc \
- src/thrift/generate/t_generator.h \
- src/thrift/generate/t_oop_generator.h \
- src/thrift/generate/t_html_generator.h
-
-thrift_SOURCES = src/thrift/main.h \
- src/thrift/main.cc \
- src/thrift/audit/t_audit.cpp \
- src/thrift/audit/t_audit.h
+ src/thrift/parse/t_container.h \
+ src/thrift/parse/t_doc.h \
+ src/thrift/parse/t_enum.h \
+ src/thrift/parse/t_enum_value.h \
+ src/thrift/parse/t_field.h \
+ src/thrift/parse/t_function.h \
+ src/thrift/parse/t_list.h \
+ src/thrift/parse/t_map.h \
+ src/thrift/parse/t_program.h \
+ src/thrift/parse/t_scope.h \
+ src/thrift/parse/t_service.h \
+ src/thrift/parse/t_set.h \
+ src/thrift/parse/t_struct.h \
+ src/thrift/parse/t_type.h \
+ src/thrift/parse/t_typedef.cc \
+ src/thrift/parse/t_typedef.h \
+ src/thrift/platform.h
# Specific client generator source
-thrift_SOURCES += src/thrift/generate/t_c_glib_generator.cc \
+thrift_SOURCES += src/thrift/generate/t_as3_generator.cc \
+ src/thrift/generate/t_c_glib_generator.cc \
+ src/thrift/generate/t_cl_generator.cc \
src/thrift/generate/t_cpp_generator.cc \
- src/thrift/generate/t_java_generator.cc \
- src/thrift/generate/t_json_generator.cc \
- src/thrift/generate/t_as3_generator.cc \
- src/thrift/generate/t_dart_generator.cc \
- src/thrift/generate/t_haxe_generator.cc \
src/thrift/generate/t_csharp_generator.cc \
- src/thrift/generate/t_netcore_generator.cc \
- src/thrift/generate/t_netcore_generator.h \
- src/thrift/generate/t_py_generator.cc \
- src/thrift/generate/t_rb_generator.cc \
- src/thrift/generate/t_perl_generator.cc \
- src/thrift/generate/t_php_generator.cc \
- src/thrift/generate/t_erl_generator.cc \
- src/thrift/generate/t_cocoa_generator.cc \
- src/thrift/generate/t_swift_generator.cc \
- src/thrift/generate/t_st_generator.cc \
- src/thrift/generate/t_ocaml_generator.cc \
- src/thrift/generate/t_hs_generator.cc \
- src/thrift/generate/t_xsd_generator.cc \
- src/thrift/generate/t_xml_generator.cc \
- src/thrift/generate/t_html_generator.cc \
- src/thrift/generate/t_js_generator.cc \
- src/thrift/generate/t_javame_generator.cc \
+ src/thrift/generate/t_d_generator.cc \
+ src/thrift/generate/t_dart_generator.cc \
src/thrift/generate/t_delphi_generator.cc \
+ src/thrift/generate/t_erl_generator.cc \
src/thrift/generate/t_go_generator.cc \
src/thrift/generate/t_gv_generator.cc \
- src/thrift/generate/t_d_generator.cc \
+ src/thrift/generate/t_haxe_generator.cc \
+ src/thrift/generate/t_hs_generator.cc \
+ src/thrift/generate/t_html_generator.cc \
+ src/thrift/generate/t_java_generator.cc \
+ src/thrift/generate/t_javame_generator.cc \
+ src/thrift/generate/t_js_generator.cc \
+ src/thrift/generate/t_json_generator.cc \
src/thrift/generate/t_lua_generator.cc \
+ src/thrift/generate/t_netcore_generator.cc \
+ src/thrift/generate/t_netcore_generator.h \
+ src/thrift/generate/t_netstd_generator.cc \
+ src/thrift/generate/t_netstd_generator.h \
+ src/thrift/generate/t_ocaml_generator.cc \
+ src/thrift/generate/t_perl_generator.cc \
+ src/thrift/generate/t_php_generator.cc \
+ src/thrift/generate/t_py_generator.cc \
+ src/thrift/generate/t_rb_generator.cc \
src/thrift/generate/t_rs_generator.cc \
- src/thrift/generate/t_cl_generator.cc
+ src/thrift/generate/t_st_generator.cc \
+ src/thrift/generate/t_swift_generator.cc \
+ src/thrift/generate/t_xml_generator.cc \
+ src/thrift/generate/t_xsd_generator.cc
thrift_CPPFLAGS = -I$(srcdir)/src
thrift_CXXFLAGS = -Wall -Wextra -pedantic -Werror
thrift_LDADD = @LEXLIB@ src/thrift/libparse.a
-if !WITH_PLUGIN
-thrift_SOURCES += $(compiler_core)
-else
-
-lib_LTLIBRARIES = libthriftc.la
-
-thrift_CPPFLAGS += -DTHRIFT_ENABLE_PLUGIN=1
-thrift_LDADD += libthriftc.la
-
-nodist_libthriftc_la_SOURCES = $(plugin_gen)
-libthriftc_la_SOURCES = $(compiler_core) \
- src/thrift/plugin/type_util.h \
- src/thrift/plugin/plugin.h \
- src/thrift/plugin/plugin.cc \
- src/thrift/plugin/plugin_output.h \
- src/thrift/plugin/plugin_output.cc \
- src/thrift/plugin/plugin.thrift \
- src/thrift/logging.cc
-
-
-libthriftc_la_CPPFLAGS = -I$(srcdir)/src -Isrc -I$(top_builddir)/lib/cpp/src -DTHRIFT_ENABLE_PLUGIN=1
-libthriftc_la_CXXFLAGS = -Wall -Wextra -pedantic
-libthriftc_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
-
-include_thriftdir = $(includedir)/thrift
-include_thrift_HEADERS = src/thrift/common.h \
- src/thrift/globals.h \
- src/thrift/logging.h \
- src/thrift/main.h \
- src/thrift/platform.h \
- src/thrift/version.h
-
-include_auditdir = $(include_thriftdir)/windows
-include_audit_HEADERS = src/thrift/audit/t_audit.h
-
-include_generatedir = $(include_thriftdir)/generate
-include_generate_HEADERS = src/thrift/generate/t_generator.h \
- src/thrift/generate/t_generator_registry.h \
- src/thrift/generate/t_oop_generator.h \
- src/thrift/generate/t_html_generator.h
-
-include_parsedir = $(include_thriftdir)/parse
-include_parse_HEADERS = src/thrift/parse/t_service.h \
- src/thrift/parse/t_program.h \
- src/thrift/parse/t_field.h \
- src/thrift/parse/t_scope.h \
- src/thrift/parse/t_typedef.h \
- src/thrift/parse/t_set.h \
- src/thrift/parse/t_const_value.h \
- src/thrift/parse/t_enum_value.h \
- src/thrift/parse/t_const.h \
- src/thrift/parse/t_list.h \
- src/thrift/parse/t_map.h \
- src/thrift/parse/t_container.h \
- src/thrift/parse/t_base_type.h \
- src/thrift/parse/t_enum.h \
- src/thrift/parse/t_function.h \
- src/thrift/parse/t_type.h \
- src/thrift/parse/t_doc.h \
- src/thrift/parse/t_struct.h
-
-include_plugindir = $(include_thriftdir)/plugin
-include_plugin_HEADERS = src/thrift/plugin/plugin.h \
- src/thrift/plugin/type_util.h \
- src/thrift/plugin/plugin_output.h
-
-include_windowsdir = $(include_thriftdir)/windows
-include_windows_HEADERS = src/thrift/windows/config.h
-endif
-
WINDOWS_DIST = \
compiler.sln \
compiler.vcxproj \
@@ -199,9 +119,9 @@
$(WINDOWS_DIST)
clean-local:
- $(RM) version.h $(plugin_gen)
+ $(RM) version.h
src/thrift/main.cc: src/thrift/version.h
style-local:
- $(CPPSTYLE_CMD)
+ $(CPPSTYLE_CMD)
diff --git a/compiler/cpp/README.md b/compiler/cpp/README.md
index 32eac9f..5c04cd8 100644
--- a/compiler/cpp/README.md
+++ b/compiler/cpp/README.md
@@ -67,7 +67,7 @@
```
mkdir cmake-build && cd cmake-build
-cmake -G "Xcode" -DWITH_PLUGIN=OFF ..
+cmake -G "Xcode" ..
cmake --build .
```
@@ -107,7 +107,7 @@
```
mkdir cmake-vs
cd cmake-vs
-cmake -G "Visual Studio 15 2017" -DWITH_PLUGIN=OFF ..
+cmake -G "Visual Studio 15 2017" ..
```
- Now open the folder cmake-vs using Visual Studio.
@@ -115,7 +115,7 @@
```
mkdir cmake-mingw32 && cd cmake-mingw32
-cmake -DCMAKE_TOOLCHAIN_FILE=../build/cmake/mingw32-toolchain.cmake -DBUILD_COMPILER=ON -DBUILD_LIBRARIES=OFF -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF ..
+cmake -DCMAKE_TOOLCHAIN_FILE=../build/cmake/mingw32-toolchain.cmake -DBUILD_COMPILER=ON -DBUILD_LIBRARIES=OFF -DBUILD_TESTING=OFF ..
cpack
```
@@ -172,4 +172,4 @@
- pls check **tests** folder
-# Have a Happy free time and holidays
\ No newline at end of file
+# Have a Happy free time and holidays
diff --git a/compiler/cpp/compiler.vcxproj b/compiler/cpp/compiler.vcxproj
index 0628b54..06c4eb4 100644
--- a/compiler/cpp/compiler.vcxproj
+++ b/compiler/cpp/compiler.vcxproj
@@ -54,11 +54,10 @@
<ClCompile Include="src\thrift\audit\t_audit.cpp" />
<ClCompile Include="src\thrift\common.cc" />
<ClCompile Include="src\thrift\generate\t_as3_generator.cc" />
- <ClCompile Include="src\thrift\generate\t_cocoa_generator.cc" />
+ <ClCompile Include="src\thrift\generate\t_c_glib_generator.cc" />
+ <ClCompile Include="src\thrift\generate\t_cl_generator.cc" />
<ClCompile Include="src\thrift\generate\t_cpp_generator.cc" />
<ClCompile Include="src\thrift\generate\t_csharp_generator.cc" />
- <ClCompile Include="src\thrift\generate\t_netcore_generator.cc" />
- <ClCompile Include="src\thrift\generate\t_c_glib_generator.cc" />
<ClCompile Include="src\thrift\generate\t_d_generator.cc" />
<ClCompile Include="src\thrift\generate\t_dart_generator.cc" />
<ClCompile Include="src\thrift\generate\t_delphi_generator.cc" />
@@ -69,11 +68,13 @@
<ClCompile Include="src\thrift\generate\t_haxe_generator.cc" />
<ClCompile Include="src\thrift\generate\t_hs_generator.cc" />
<ClCompile Include="src\thrift\generate\t_html_generator.cc" />
- <ClCompile Include="src\thrift\generate\t_javame_generator.cc" />
<ClCompile Include="src\thrift\generate\t_java_generator.cc" />
+ <ClCompile Include="src\thrift\generate\t_javame_generator.cc" />
<ClCompile Include="src\thrift\generate\t_js_generator.cc" />
<ClCompile Include="src\thrift\generate\t_json_generator.cc" />
<ClCompile Include="src\thrift\generate\t_lua_generator.cc" />
+ <ClCompile Include="src\thrift\generate\t_netcore_generator.cc" />
+ <ClCompile Include="src\thrift\generate\t_netstd_generator.cc" />
<ClCompile Include="src\thrift\generate\t_ocaml_generator.cc" />
<ClCompile Include="src\thrift\generate\t_perl_generator.cc" />
<ClCompile Include="src\thrift\generate\t_php_generator.cc" />
@@ -247,4 +248,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/compiler/cpp/compiler.vcxproj.filters b/compiler/cpp/compiler.vcxproj.filters
index b96865b..5a57589 100644
--- a/compiler/cpp/compiler.vcxproj.filters
+++ b/compiler/cpp/compiler.vcxproj.filters
@@ -161,6 +161,18 @@
<ClCompile Include="src\generate\t_rb_generator.cc">
<Filter>generate</Filter>
</ClCompile>
+ <ClCompile Include="src\generate\t_netcore_generator.h">
+ <Filter>generate</Filter>
+ </ClCompile>
+ <ClCompile Include="src\generate\t_netstd_generator.h">
+ <Filter>generate</Filter>
+ </ClCompile>
+ <ClCompile Include="src\generate\t_netcore_generator.cc">
+ <Filter>generate</Filter>
+ </ClCompile>
+ <ClCompile Include="src\generate\t_netstd_generator.cc">
+ <Filter>generate</Filter>
+ </ClCompile>
<ClCompile Include="src\generate\t_rs_generator.cc">
<Filter>generate</Filter>
</ClCompile>
diff --git a/compiler/cpp/src/Makefile.am b/compiler/cpp/src/Makefile.am
index bc2c5cb..b3139e2 100644
--- a/compiler/cpp/src/Makefile.am
+++ b/compiler/cpp/src/Makefile.am
@@ -37,51 +37,3 @@
clean-local:
$(RM) thrift/thriftl.cc thrift/thrifty.cc thrift/thrifty.h thrift/thrifty.hh
-
-if WITH_PLUGIN
-noinst_PROGRAMS = thrift/thrift-bootstrap
-
-thrift_thrift_bootstrap_SOURCES = \
- thrift/common.h \
- thrift/common.cc \
- thrift/audit/t_audit.h \
- thrift/audit/t_audit.cpp \
- thrift/generate/t_generator.cc \
- thrift/generate/t_generator_registry.h \
- thrift/globals.h \
- thrift/platform.h \
- thrift/logging.h \
- thrift/parse/t_doc.h \
- thrift/parse/t_type.h \
- thrift/parse/t_base_type.h \
- thrift/parse/t_enum.h \
- thrift/parse/t_enum_value.h \
- thrift/parse/t_typedef.h \
- thrift/parse/t_typedef.cc \
- thrift/parse/t_container.h \
- thrift/parse/t_list.h \
- thrift/parse/t_set.h \
- thrift/parse/t_map.h \
- thrift/parse/t_struct.h \
- thrift/parse/t_field.h \
- thrift/parse/t_service.h \
- thrift/parse/t_function.h \
- thrift/parse/t_program.h \
- thrift/parse/t_scope.h \
- thrift/parse/t_const.h \
- thrift/parse/t_const_value.h \
- thrift/parse/parse.cc \
- thrift/generate/t_generator.h \
- thrift/generate/t_oop_generator.h \
- thrift/generate/t_html_generator.h \
- thrift/windows/config.h \
- thrift/version.h \
- thrift/generate/t_cpp_generator.cc \
- thrift/main.h \
- thrift/main.cc
-
-main.cc: version.h
-
-thrift_thrift_bootstrap_CXXFLAGS = -Wall -Wextra -pedantic
-thrift_thrift_bootstrap_LDADD = @LEXLIB@ thrift/libparse.a
-endif
diff --git a/compiler/cpp/src/thrift/audit/t_audit.cpp b/compiler/cpp/src/thrift/audit/t_audit.cpp
index ef39d60..fbce15c 100644
--- a/compiler/cpp/src/thrift/audit/t_audit.cpp
+++ b/compiler/cpp/src/thrift/audit/t_audit.cpp
@@ -54,18 +54,16 @@
const std::map<std::string, std::string>& newNamespaceMap = newProgram->get_all_namespaces();
const std::map<std::string, std::string>& oldNamespaceMap = oldProgram->get_all_namespaces();
- for(std::map<std::string, std::string>::const_iterator oldNamespaceMapIt = oldNamespaceMap.begin();
- oldNamespaceMapIt != oldNamespaceMap.end();
- oldNamespaceMapIt++)
+ for(const auto & oldNamespaceMapIt : oldNamespaceMap)
{
- std::map<std::string, std::string>::const_iterator newNamespaceMapIt = newNamespaceMap.find(oldNamespaceMapIt->first);
+ auto newNamespaceMapIt = newNamespaceMap.find(oldNamespaceMapIt.first);
if(newNamespaceMapIt == newNamespaceMap.end())
{
- thrift_audit_warning(1, "Language %s not found in new thrift file\n", (oldNamespaceMapIt->first).c_str());
+ thrift_audit_warning(1, "Language %s not found in new thrift file\n", (oldNamespaceMapIt.first).c_str());
}
- else if((newNamespaceMapIt->second) != oldNamespaceMapIt->second)
+ else if((newNamespaceMapIt->second) != oldNamespaceMapIt.second)
{
- thrift_audit_warning(1, "Namespace %s changed in new thrift file\n", (oldNamespaceMapIt->second).c_str());
+ thrift_audit_warning(1, "Namespace %s changed in new thrift file\n", (oldNamespaceMapIt.second).c_str());
}
}
}
@@ -73,15 +71,13 @@
void compare_enum_values(t_enum* newEnum,t_enum* oldEnum)
{
const std::vector<t_enum_value*>& oldEnumValues = oldEnum->get_constants();
- for(std::vector<t_enum_value*>::const_iterator oldEnumValuesIt = oldEnumValues.begin();
- oldEnumValuesIt != oldEnumValues.end();
- oldEnumValuesIt++)
+ for(auto oldEnumValue : oldEnumValues)
{
- int enumValue = (*oldEnumValuesIt)->get_value();
+ int enumValue = oldEnumValue->get_value();
t_enum_value* newEnumValue = newEnum->get_constant_by_value(enumValue);
- if(newEnumValue != NULL)
+ if(newEnumValue != nullptr)
{
- std::string enumName = (*oldEnumValuesIt)->get_name();
+ std::string enumName = oldEnumValue->get_name();
if(enumName != newEnumValue->get_name())
{
thrift_audit_warning(1, "Name of the value %d changed in enum %s\n", enumValue, oldEnum->get_name().c_str());
@@ -175,9 +171,9 @@
// This function returns 'true' if the default values are same. Returns false if they are different.
bool compare_defaults(t_const_value* newStructDefault, t_const_value* oldStructDefault)
{
- if(newStructDefault == NULL && oldStructDefault == NULL) return true;
- else if(newStructDefault == NULL && oldStructDefault != NULL) return false;
- else if (newStructDefault != NULL && oldStructDefault == NULL) return false;
+ if(newStructDefault == nullptr && oldStructDefault == nullptr) return true;
+ else if(newStructDefault == nullptr && oldStructDefault != nullptr) return false;
+ else if (newStructDefault != nullptr && oldStructDefault == nullptr) return false;
if(newStructDefault->get_type() != oldStructDefault->get_type())
{
@@ -255,8 +251,8 @@
std::string structName = oldStructName.empty() ? oldStruct->get_name() : oldStructName;
const std::vector<t_field*>& oldStructMembersInIdOrder = oldStruct->get_sorted_members();
const std::vector<t_field*>& newStructMembersInIdOrder = newStruct->get_sorted_members();
- std::vector<t_field*>::const_iterator oldStructMemberIt = oldStructMembersInIdOrder.begin();
- std::vector<t_field*>::const_iterator newStructMemberIt = newStructMembersInIdOrder.begin();
+ auto oldStructMemberIt = oldStructMembersInIdOrder.begin();
+ auto newStructMemberIt = newStructMembersInIdOrder.begin();
// Since we have the struct members in their ID order, comparing their IDs can be done by traversing the two member
// lists together.
@@ -352,27 +348,23 @@
{
std::map<std::string, t_function*> newFunctionMap;
std::map<std::string, t_function*>::iterator newFunctionMapIt;
- for(std::vector<t_function*>::const_iterator newFunctionIt = newFunctionList.begin();
- newFunctionIt != newFunctionList.end();
- newFunctionIt++)
+ for(auto newFunctionIt : newFunctionList)
{
- newFunctionMap[(*newFunctionIt)->get_name()] = *newFunctionIt;
+ newFunctionMap[newFunctionIt->get_name()] = newFunctionIt;
}
- for(std::vector<t_function*>::const_iterator oldFunctionIt = oldFunctionList.begin();
- oldFunctionIt != oldFunctionList.end();
- oldFunctionIt++)
+ for(auto oldFunctionIt : oldFunctionList)
{
- newFunctionMapIt = newFunctionMap.find((*oldFunctionIt)->get_name());
+ newFunctionMapIt = newFunctionMap.find(oldFunctionIt->get_name());
if(newFunctionMapIt == newFunctionMap.end())
{
- thrift_audit_failure("New Thrift File has missing function %s\n",(*oldFunctionIt)->get_name().c_str());
+ thrift_audit_failure("New Thrift File has missing function %s\n",oldFunctionIt->get_name().c_str());
continue;
}
else
{
//Function is found in both thrift files. Compare return type and argument list
- compare_single_function(newFunctionMapIt->second, *oldFunctionIt);
+ compare_single_function(newFunctionMapIt->second, oldFunctionIt);
}
}
@@ -383,18 +375,16 @@
std::vector<t_service*>::const_iterator oldServiceIt;
std::map<std::string, t_service*> newServiceMap;
- for(std::vector<t_service*>::const_iterator newServiceIt = newServices.begin();
- newServiceIt != newServices.end();
- newServiceIt++)
+ for(auto newService : newServices)
{
- newServiceMap[(*newServiceIt)->get_name()] = *newServiceIt;
+ newServiceMap[newService->get_name()] = newService;
}
for(oldServiceIt = oldServices.begin(); oldServiceIt != oldServices.end(); oldServiceIt++)
{
const std::string oldServiceName = (*oldServiceIt)->get_name();
- std::map<std::string, t_service*>::iterator newServiceMapIt = newServiceMap.find(oldServiceName);
+ auto newServiceMapIt = newServiceMap.find(oldServiceName);
if(newServiceMapIt == newServiceMap.end())
{
@@ -405,12 +395,12 @@
t_service* oldServiceExtends = (*oldServiceIt)->get_extends();
t_service* newServiceExtends = (newServiceMapIt->second)->get_extends();
- if(oldServiceExtends == NULL)
+ if(oldServiceExtends == nullptr)
{
// It is fine to add extends. So if service in older thrift did not have any extends, we are fine.
// DO Nothing
}
- else if(oldServiceExtends != NULL && newServiceExtends == NULL)
+ else if(oldServiceExtends != nullptr && newServiceExtends == nullptr)
{
thrift_audit_failure("Change in Service inheritance for %s\n", oldServiceName.c_str());
}
diff --git a/compiler/cpp/src/thrift/common.cc b/compiler/cpp/src/thrift/common.cc
index 3a2b9d3..fb1832d 100644
--- a/compiler/cpp/src/thrift/common.cc
+++ b/compiler/cpp/src/thrift/common.cc
@@ -58,10 +58,6 @@
}
/**
- * Those are not really needed for plugins but causes link errors without
- */
-
-/**
* The location of the last parsed doctext comment.
*/
int g_doctext_lineno;
diff --git a/compiler/cpp/src/thrift/generate/t_as3_generator.cc b/compiler/cpp/src/thrift/generate/t_as3_generator.cc
index 41724fe..dd4d166 100644
--- a/compiler/cpp/src/thrift/generate/t_as3_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_as3_generator.cc
@@ -68,20 +68,20 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
- void generate_consts(std::vector<t_const*> consts);
+ void generate_consts(std::vector<t_const*> consts) override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
void print_const_value(std::ostream& out,
std::string name,
@@ -191,7 +191,7 @@
std::string function_signature(t_function* tfunction, std::string prefix = "");
std::string argument_list(t_struct* tstruct);
std::string type_to_enum(t_type* ttype);
- std::string get_enum_class_name(t_type* type);
+ std::string get_enum_class_name(t_type* type) override;
bool type_can_be_null(t_type* ttype) {
ttype = get_true_type(ttype);
@@ -2519,9 +2519,7 @@
bool is_first = true;
bool was_previous_char_upper = false;
- for (string::iterator iter = name.begin(); iter != name.end(); ++iter) {
- string::value_type character = (*iter);
-
+ for (char character : name) {
bool is_upper = isupper(character);
if (is_upper && !is_first && !was_previous_char_upper) {
diff --git a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
index be3bad1..f1531cc 100644
--- a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
@@ -103,16 +103,16 @@
}
/* initialization and destruction */
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/* generation functions */
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_consts(vector<t_const*> consts);
- void generate_struct(t_struct* tstruct);
- void generate_service(t_service* tservice);
- void generate_xception(t_struct* tstruct);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_consts(vector<t_const*> consts) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_service(t_service* tservice) override;
+ void generate_xception(t_struct* tstruct) override;
private:
/* file streams */
@@ -253,15 +253,13 @@
if (!includes.empty()) {
f_types_ << "/* other thrift includes */" << endl;
- for (vector<t_program*>::const_iterator iter = includes.begin();
- iter != includes.end();
- ++iter) {
- const std::string& include_nspace = (*iter)->get_namespace("c_glib");
+ for (auto include : includes) {
+ const std::string& include_nspace = include->get_namespace("c_glib");
std::string include_nspace_prefix =
include_nspace.empty() ? "" : initial_caps_to_underscores(include_nspace) + "_";
f_types_ << "#include \"" << include_nspace_prefix
- << initial_caps_to_underscores((*iter)->get_name()) << "_types.h\"" << endl;
+ << initial_caps_to_underscores(include->get_name()) << "_types.h\"" << endl;
}
f_types_ << endl;
}
@@ -269,11 +267,11 @@
/* include custom headers */
const vector<string>& c_includes = program_->get_c_includes();
f_types_ << "/* custom thrift includes */" << endl;
- for (size_t i = 0; i < c_includes.size(); ++i) {
- if (c_includes[i][0] == '<') {
- f_types_ << "#include " << c_includes[i] << endl;
+ for (const auto & c_include : c_includes) {
+ if (c_include[0] == '<') {
+ f_types_ << "#include " << c_include << endl;
} else {
- f_types_ << "#include \"" << c_includes[i] << "\"" << endl;
+ f_types_ << "#include \"" << c_include << "\"" << endl;
}
}
f_types_ << endl;
@@ -4507,23 +4505,21 @@
***************************************/
/**
- * Upper case a string. Wraps boost's string utility.
+ * Upper case a string.
*/
string to_upper_case(string name) {
string s(name);
std::transform(s.begin(), s.end(), s.begin(), ::toupper);
return s;
- // return boost::to_upper_copy (name);
}
/**
- * Lower case a string. Wraps boost's string utility.
+ * Lower case a string.
*/
string to_lower_case(string name) {
string s(name);
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
- // return boost::to_lower_copy (name);
}
/**
diff --git a/compiler/cpp/src/thrift/generate/t_cl_generator.cc b/compiler/cpp/src/thrift/generate/t_cl_generator.cc
index 628d0d8..ad7c0ef 100644
--- a/compiler/cpp/src/thrift/generate/t_cl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cl_generator.cc
@@ -26,7 +26,6 @@
#include <vector>
#include <stdlib.h>
-#include <boost/tokenizer.hpp>
#include <sys/stat.h>
#include <sys/types.h>
#include <sstream>
@@ -35,6 +34,7 @@
#include "thrift/platform.h"
#include "t_oop_generator.h"
+
using namespace std;
@@ -70,15 +70,15 @@
copy_options_ = option_string;
}
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
- void generate_typedef (t_typedef* ttypedef);
- void generate_enum (t_enum* tenum);
- void generate_const (t_const* tconst);
- void generate_struct (t_struct* tstruct);
- void generate_xception (t_struct* txception);
- void generate_service (t_service* tservice);
+ void generate_typedef (t_typedef* ttypedef) override;
+ void generate_enum (t_enum* tenum) override;
+ void generate_const (t_const* tconst) override;
+ void generate_struct (t_struct* tstruct) override;
+ void generate_xception (t_struct* txception) override;
+ void generate_service (t_service* tservice) override;
void generate_cl_struct (std::ostream& out, t_struct* tstruct, bool is_exception);
void generate_cl_struct_internal (std::ostream& out, t_struct* tstruct, bool is_exception);
void generate_exception_sig(std::ostream& out, t_function* f);
@@ -128,9 +128,9 @@
string f_types_name = program_dir + "/" + program_name_ + "-types.lisp";
string f_vars_name = program_dir + "/" + program_name_ + "-vars.lisp";
- f_types_.open(f_types_name.c_str());
+ f_types_.open(f_types_name);
f_types_ << cl_autogen_comment() << endl;
- f_vars_.open(f_vars_name.c_str());
+ f_vars_.open(f_vars_name);
f_vars_ << cl_autogen_comment() << endl;
package_def(f_types_);
@@ -139,7 +139,7 @@
if (!no_asd) {
string f_asd_name = program_dir + "/" + system_prefix + program_name_ + ".asd";
- f_asd_.open(f_asd_name.c_str());
+ f_asd_.open(f_asd_name);
f_asd_ << cl_autogen_comment() << endl;
asdf_def(f_asd_);
}
@@ -152,8 +152,8 @@
const vector<t_program*>& includes = program_->get_includes();
string result = "";
result += ":depends-on (:thrift";
- for (size_t i = 0; i < includes.size(); ++i) {
- result += " :" + system_prefix + underscore(includes[i]->get_name());
+ for (auto include : includes) {
+ result += " :" + system_prefix + underscore(include->get_name());
}
result += ")\n";
return result;
@@ -215,8 +215,8 @@
out << "(thrift:def-package :" << package();
if ( includes.size() > 0 ) {
out << " :use (";
- for (size_t i = 0; i < includes.size(); ++i) {
- out << " :" << includes[i]->get_name();
+ for (auto include : includes) {
+ out << " :" << include->get_name();
}
out << ")";
}
diff --git a/compiler/cpp/src/thrift/generate/t_cocoa_generator.cc b/compiler/cpp/src/thrift/generate/t_cocoa_generator.cc
deleted file mode 100644
index ac644f5..0000000
--- a/compiler/cpp/src/thrift/generate/t_cocoa_generator.cc
+++ /dev/null
@@ -1,3309 +0,0 @@
-/*
- * 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.
- */
-
-#include <string>
-#include <fstream>
-#include <iostream>
-#include <vector>
-
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sstream>
-#include "thrift/platform.h"
-#include "thrift/generate/t_oop_generator.h"
-
-using std::map;
-using std::ostream;
-using std::ofstream;
-using std::ostringstream;
-using std::string;
-using std::stringstream;
-using std::vector;
-
-static const string endl = "\n"; // avoid ostream << std::endl flushes
-
-/**
- * Objective-C code generator.
- *
- * mostly copy/pasting/tweaking from mcslee's work.
- */
-class t_cocoa_generator : public t_oop_generator {
-public:
- t_cocoa_generator(t_program* program,
- const std::map<std::string, std::string>& parsed_options,
- const std::string& option_string)
- : t_oop_generator(program) {
- (void)option_string;
- std::map<std::string, std::string>::const_iterator iter;
-
- log_unexpected_ = false;
- validate_required_ = false;
- async_clients_ = false;
- promise_kit_ = false;
- debug_descriptions_ = false;
- pods_ = false;
- for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
- if( iter->first.compare("log_unexpected") == 0) {
- log_unexpected_ = true;
- } else if( iter->first.compare("validate_required") == 0) {
- validate_required_ = true;
- } else if( iter->first.compare("async_clients") == 0) {
- async_clients_ = true;
- } else if( iter->first.compare("promise_kit") == 0) {
- promise_kit_ = true;
- } else if( iter->first.compare("debug_descriptions") == 0) {
- debug_descriptions_ = true;
- } else if( iter->first.compare("pods") == 0) {
- pods_ = true;
- } else {
- throw "unknown option cocoa:" + iter->first;
- }
- }
-
- out_dir_base_ = "gen-cocoa";
- }
-
- /**
- * Init and close methods
- */
-
- void init_generator();
- void close_generator();
-
- void generate_consts(std::vector<t_const*> consts);
-
- /**
- * Program-level generation functions
- */
-
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
-
- void print_const_value(ostream& out,
- string name,
- t_type* type,
- t_const_value* value,
- bool defval = false);
- std::string render_const_value(ostream& out,
- t_type* type,
- t_const_value* value,
- bool box_it = false);
-
- void generate_cocoa_struct(t_struct* tstruct, bool is_exception);
- void generate_cocoa_struct_interface(std::ostream& out,
- t_struct* tstruct,
- bool is_xception = false);
- void generate_cocoa_struct_implementation(std::ostream& out,
- t_struct* tstruct,
- bool is_xception = false,
- bool is_result = false);
- void generate_cocoa_struct_initializer_signature(std::ostream& out, t_struct* tstruct);
- void generate_cocoa_struct_init_with_coder_method(ostream& out,
- t_struct* tstruct,
- bool is_exception);
- void generate_cocoa_struct_encode_with_coder_method(ostream& out,
- t_struct* tstruct,
- bool is_exception);
- void generate_cocoa_struct_copy_method(ostream& out,
- t_struct* tstruct,
- bool is_exception);
- void generate_cocoa_struct_hash_method(ostream& out, t_struct* tstruct);
- void generate_cocoa_struct_is_equal_method(ostream& out,
- t_struct* tstruct,
- bool is_exception);
- void generate_cocoa_struct_field_accessor_implementations(std::ostream& out,
- t_struct* tstruct,
- bool is_exception);
- void generate_cocoa_struct_reader(std::ostream& out, t_struct* tstruct);
- void generate_cocoa_struct_result_writer(std::ostream& out, t_struct* tstruct);
- void generate_cocoa_struct_writer(std::ostream& out, t_struct* tstruct);
- void generate_cocoa_struct_validator(std::ostream& out, t_struct* tstruct);
- void generate_cocoa_struct_description(std::ostream& out, t_struct* tstruct);
-
- std::string function_result_helper_struct_type(t_service *tservice, t_function* tfunction);
- std::string function_args_helper_struct_type(t_service* tservice, t_function* tfunction);
- void generate_function_helpers(t_service *tservice, t_function* tfunction);
-
- /**
- * Service-level generation functions
- */
-
- void generate_cocoa_service_protocol(std::ostream& out, t_service* tservice);
- void generate_cocoa_service_async_protocol(std::ostream& out, t_service* tservice);
-
- void generate_cocoa_service_client_interface(std::ostream& out, t_service* tservice);
- void generate_cocoa_service_client_async_interface(std::ostream& out, t_service* tservice);
-
- void generate_cocoa_service_client_send_function_implementation(ostream& out,
- t_service* tservice,
- t_function* tfunction,
- bool needs_protocol);
- void generate_cocoa_service_client_send_function_invocation(ostream& out, t_function* tfunction);
- void generate_cocoa_service_client_send_async_function_invocation(ostream& out,
- t_function* tfunction,
- string failureBlockName);
- void generate_cocoa_service_client_recv_function_implementation(ostream& out,
- t_service* tservice,
- t_function* tfunction,
- bool needs_protocol);
- void generate_cocoa_service_client_implementation(std::ostream& out, t_service* tservice);
- void generate_cocoa_service_client_async_implementation(std::ostream& out, t_service* tservice);
-
- void generate_cocoa_service_server_interface(std::ostream& out, t_service* tservice);
- void generate_cocoa_service_server_implementation(std::ostream& out, t_service* tservice);
- void generate_cocoa_service_helpers(t_service* tservice);
- void generate_service_client(t_service* tservice);
- void generate_service_server(t_service* tservice);
- void generate_process_function(t_service* tservice, t_function* tfunction);
-
- /**
- * Serialization constructs
- */
-
- void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string fieldName);
-
- void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
-
- void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
-
- void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
-
- void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
-
- void generate_deserialize_list_element(std::ostream& out,
- t_list* tlist,
- std::string prefix = "");
-
- void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
-
- void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string fieldName = "");
-
- void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
-
- void generate_serialize_map_element(std::ostream& out,
- t_map* tmap,
- std::string iter,
- std::string map);
-
- void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
-
- void generate_serialize_list_element(std::ostream& out,
- t_list* tlist,
- std::string index,
- std::string listName);
-
- /**
- * Helper rendering functions
- */
-
- std::string cocoa_prefix();
- std::string cocoa_imports();
- std::string cocoa_thrift_imports();
- std::string type_name(t_type* ttype, bool class_ref = false, bool needs_mutable = false);
- std::string element_type_name(t_type* ttype);
- std::string base_type_name(t_base_type* tbase);
- std::string declare_property(t_field* tfield);
- std::string declare_property_isset(t_field* tfield);
- std::string declare_property_unset(t_field* tfield);
- std::string invalid_return_statement(t_function* tfunction);
- std::string function_signature(t_function* tfunction, bool include_error);
- std::string async_function_signature(t_function* tfunction, bool include_error);
- std::string promise_function_signature(t_function* tfunction);
- std::string argument_list(t_struct* tstruct, string protocol_name, bool include_error);
- std::string type_to_enum(t_type* ttype);
- std::string format_string_for_type(t_type* type);
- std::string format_cast_for_type(t_type* type);
- std::string call_field_setter(t_field* tfield, std::string fieldName);
- std::string box(t_type *ttype, std::string field_name);
- std::string unbox(t_type* ttype, std::string field_name);
- std::string getter_name(string field_name);
- std::string setter_name(string field_name);
-
- bool type_can_be_copy(t_type* ttype) {
- ttype = get_true_type(ttype);
-
- return ttype->is_string();
- }
-
- bool type_can_be_null(t_type* ttype) {
- ttype = get_true_type(ttype);
-
- return ttype->is_container() || ttype->is_struct() || ttype->is_xception()
- || ttype->is_string();
- }
-
-private:
- std::string cocoa_prefix_;
- std::string constants_declarations_;
- int error_constant_;
-
- /**
- * File streams
- */
-
- ofstream_with_content_based_conditional_update f_header_;
- ofstream_with_content_based_conditional_update f_impl_;
-
- bool log_unexpected_;
- bool validate_required_;
- bool async_clients_;
- bool promise_kit_;
- bool debug_descriptions_;
- bool pods_;
-};
-
-/**
- * Prepares for file generation by opening up the necessary file output
- * streams.
- */
-void t_cocoa_generator::init_generator() {
- // Make output directory
- MKDIR(get_out_dir().c_str());
- cocoa_prefix_ = program_->get_namespace("cocoa");
-
- // we have a .h header file...
- string f_header_name = cocoa_prefix_ + capitalize(program_name_) + ".h";
- string f_header_fullname = get_out_dir() + f_header_name;
- f_header_.open(f_header_fullname.c_str());
-
- f_header_ << autogen_comment() << endl;
-
- f_header_ << cocoa_imports() << cocoa_thrift_imports();
-
- // ...and a .m implementation file
- string f_impl_name = cocoa_prefix_ + capitalize(program_name_) + ".m";
- string f_impl_fullname = get_out_dir() + f_impl_name;
- f_impl_.open(f_impl_fullname.c_str());
-
- f_impl_ << autogen_comment() << endl;
-
- f_impl_ << cocoa_imports() << cocoa_thrift_imports() << "#import \"" << f_header_name << "\""
- << endl << endl;
-
- error_constant_ = 60000;
-}
-
-/**
- * Prints standard Cocoa imports
- *
- * @return List of imports for Cocoa libraries
- */
-string t_cocoa_generator::cocoa_imports() {
- return string() + "#import <Foundation/Foundation.h>\n" + "\n";
-}
-
-/**
- * Prints thrift runtime imports
- *
- * @return List of imports necessary for thrift runtime
- */
-string t_cocoa_generator::cocoa_thrift_imports() {
-
- vector<string> includes_list;
- includes_list.push_back("TProtocol.h");
- includes_list.push_back("TProtocolFactory.h");
- includes_list.push_back("TApplicationError.h");
- includes_list.push_back("TProtocolError.h");
- includes_list.push_back("TProtocolUtil.h");
- includes_list.push_back("TProcessor.h");
- includes_list.push_back("TBase.h");
- includes_list.push_back("TAsyncTransport.h");
- includes_list.push_back("TBaseClient.h");
-
- std::ostringstream includes;
-
- vector<string>::const_iterator i_iter;
- for (i_iter=includes_list.begin(); i_iter!=includes_list.end(); ++i_iter) {
- includes << "#import ";
- if (pods_) {
- includes << "<Thrift/" << *i_iter << ">";
- } else {
- includes << "\"" << *i_iter << "\"";
- }
- includes << endl;
- }
-
- includes << endl;
-
- if (promise_kit_) {
- includes << "#import ";
- if (pods_) {
- includes << "<PromiseKit/PromiseKit.h>";
- } else {
- includes << "\"PromiseKit.h\"";
- }
- includes << endl;
- }
-
- // Include other Thrift includes
- const vector<t_program*>& other_includes = program_->get_includes();
- for (size_t i = 0; i < other_includes.size(); ++i) {
- includes << "#import \""
- << other_includes[i]->get_namespace("cocoa")
- << capitalize(other_includes[i]->get_name())
- << ".h\"" << endl;
- }
-
- includes << endl;
-
- return includes.str();
-}
-
-/**
- * Finish up generation.
- */
-void t_cocoa_generator::close_generator() {
- // stick our constants declarations at the end of the header file
- // since they refer to things we are defining.
- f_header_ << constants_declarations_ << endl;
-}
-
-/**
- * Generates a typedef. This is just a simple 1-liner in objective-c
- *
- * @param ttypedef The type definition
- */
-void t_cocoa_generator::generate_typedef(t_typedef* ttypedef) {
- if (ttypedef->get_type()->is_map()) {
- t_map *map = (t_map *)ttypedef->get_type();
- if (map->get_key_type()->is_struct()) {
- f_header_ << indent() << "@class " << type_name(map->get_key_type(), true) << ";" << endl;
- }
- if (map->get_val_type()->is_struct()) {
- f_header_ << indent() << "@class " << type_name(map->get_val_type(), true) << ";" << endl;
- }
- }
- else if (ttypedef->get_type()->is_set()) {
- t_set *set = (t_set *)ttypedef->get_type();
- if (set->get_elem_type()->is_struct()) {
- f_header_ << indent() << "@class " << type_name(set->get_elem_type(), true) << ";" << endl;
- }
- }
- else if (ttypedef->get_type()->is_list()) {
- t_list *list = (t_list *)ttypedef->get_type();
- if (list->get_elem_type()->is_struct()) {
- f_header_ << indent() << "@class " << type_name(list->get_elem_type(), true) << ";" << endl;
- }
- }
- f_header_ << indent() << "typedef " << type_name(ttypedef->get_type()) << " " << cocoa_prefix_
- << ttypedef->get_symbolic() << ";" << endl << endl;
- if (ttypedef->get_type()->is_container()) {
- f_header_ << indent() << "typedef " << type_name(ttypedef->get_type(), false, true) << " " << cocoa_prefix_
- << "Mutable" << ttypedef->get_symbolic() << ";" << endl << endl;
- }
-}
-
-/**
- * Generates code for an enumerated type. In Objective-C, this is
- * essentially the same as the thrift definition itself, instead using
- * NS_ENUM keyword in Objective-C. For namespace purposes, the name of
- * the enum is prefixed to each element in keeping with Cocoa & Swift
- * standards.
- *
- * @param tenum The enumeration
- */
-void t_cocoa_generator::generate_enum(t_enum* tenum) {
- f_header_ << indent() << "typedef NS_ENUM(SInt32, " << cocoa_prefix_ << tenum->get_name() << ") {" << endl;
- indent_up();
-
- vector<t_enum_value*> constants = tenum->get_constants();
- vector<t_enum_value*>::iterator c_iter;
- bool first = true;
- for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
- if (first) {
- first = false;
- } else {
- f_header_ << "," << endl;
- }
- f_header_ << indent() << cocoa_prefix_ << tenum->get_name() << (*c_iter)->get_name();
- f_header_ << " = " << (*c_iter)->get_value();
- }
-
- indent_down();
- f_header_ << endl << "};" << endl << endl;
-}
-
-/**
- * Generates a class that holds all the constants.
- */
-void t_cocoa_generator::generate_consts(std::vector<t_const*> consts) {
- std::ostringstream const_interface;
-
- const_interface << "FOUNDATION_EXPORT NSString *" << cocoa_prefix_ << capitalize(program_name_) << "ErrorDomain;" << endl
- << endl;
-
-
- bool needs_class = false;
-
- // Public constants for base types & strings
- vector<t_const*>::iterator c_iter;
- for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
- t_type* type = (*c_iter)->get_type()->get_true_type();
- if (!type->is_container() && !type->is_struct()) {
- const_interface << "FOUNDATION_EXPORT " << type_name(type) << " "
- << cocoa_prefix_ << capitalize((*c_iter)->get_name()) << ";" << endl;
- }
- else {
- needs_class = true;
- }
- }
-
-
- string constants_class_name = cocoa_prefix_ + capitalize(program_name_) + "Constants";
-
- if (needs_class) {
-
- const_interface << endl;
-
- const_interface << "@interface " << constants_class_name << " : NSObject ";
- scope_up(const_interface);
- scope_down(const_interface);
-
- // getter method for each constant defined.
- for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
- string name = (*c_iter)->get_name();
- t_type* type = (*c_iter)->get_type()->get_true_type();
- if (type->is_container() || type->is_struct()) {
- t_type* type = (*c_iter)->get_type();
- const_interface << endl << "+ (" << type_name(type) << ") " << name << ";" << endl;
- }
- }
-
- const_interface << endl << "@end";
- }
-
- // this gets spit into the header file in ::close_generator
- constants_declarations_ = const_interface.str();
-
- f_impl_ << "NSString *" << cocoa_prefix_ << capitalize(program_name_) << "ErrorDomain = "
- << "@\"" << cocoa_prefix_ << capitalize(program_name_) << "ErrorDomain\";" << endl << endl;
-
- // variables in the .m hold all simple constant values
- for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
- string name = (*c_iter)->get_name();
- t_type* type = (*c_iter)->get_type();
- f_impl_ << type_name(type) << " " << cocoa_prefix_ << name;
- t_type* ttype = type->get_true_type();
- if (!ttype->is_container() && !ttype->is_struct()) {
- f_impl_ << " = " << render_const_value(f_impl_, type, (*c_iter)->get_value());
- }
- f_impl_ << ";" << endl;
- }
- f_impl_ << endl;
-
- if (needs_class) {
-
- f_impl_ << "@implementation " << constants_class_name << endl << endl;
-
- // initialize complex constants when the class is loaded
- f_impl_ << "+ (void) initialize ";
- scope_up(f_impl_);
-
- for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
- t_type* ttype = (*c_iter)->get_type()->get_true_type();
- if (ttype->is_container() || ttype->is_struct()) {
- f_impl_ << endl;
- print_const_value(f_impl_,
- cocoa_prefix_ + (*c_iter)->get_name(),
- (*c_iter)->get_type(),
- (*c_iter)->get_value(),
- false);
- f_impl_ << ";" << endl;
- }
- }
- scope_down(f_impl_);
-
- // getter method for each constant
- for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
- string name = (*c_iter)->get_name();
- t_type* type = (*c_iter)->get_type()->get_true_type();
- if (type->is_container() || type->is_struct()) {
- f_impl_ << endl << "+ (" << type_name(type) << ") " << name << " ";
- scope_up(f_impl_);
- indent(f_impl_) << "return " << cocoa_prefix_ << name << ";" << endl;
- scope_down(f_impl_);
- }
- }
-
- f_impl_ << "@end" << endl << endl;
- }
-}
-
-/**
- * Generates a struct definition for a thrift data type. This is a class
- * with protected data members, read(), write(), and getters and setters.
- *
- * @param tstruct The struct definition
- */
-void t_cocoa_generator::generate_struct(t_struct* tstruct) {
- generate_cocoa_struct_interface(f_header_, tstruct, false);
- generate_cocoa_struct_implementation(f_impl_, tstruct, false);
-}
-
-/**
- * Exceptions are structs, but they inherit from NSException
- *
- * @param tstruct The struct definition
- */
-void t_cocoa_generator::generate_xception(t_struct* txception) {
- generate_cocoa_struct_interface(f_header_, txception, true);
- generate_cocoa_struct_implementation(f_impl_, txception, true);
-}
-
-/**
- * Generate the interface for a struct
- *
- * @param tstruct The struct definition
- */
-void t_cocoa_generator::generate_cocoa_struct_interface(ostream& out,
- t_struct* tstruct,
- bool is_exception) {
-
- if (is_exception) {
- out << "enum {" << endl
- << " " << cocoa_prefix_ << capitalize(program_name_) << "Error" << tstruct->get_name() << " = -" << error_constant_++ << endl
- << "};" << endl
- << endl;
- }
-
- out << "@interface " << cocoa_prefix_ << tstruct->get_name() << " : ";
-
- if (is_exception) {
- out << "NSError ";
- } else {
- out << "NSObject ";
- }
- out << "<TBase, NSCoding, NSCopying> " << endl;
-
- out << endl;
-
- // properties
- const vector<t_field*>& members = tstruct->get_members();
- if (members.size() > 0) {
- vector<t_field*>::const_iterator m_iter;
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- out << indent() << declare_property(*m_iter) << endl;
- out << indent() << declare_property_isset(*m_iter) << endl;
- out << indent() << declare_property_unset(*m_iter) << endl;
- out << endl;
- }
- }
-
- out << endl;
-
- // initializer for all fields
- if (!members.empty()) {
- generate_cocoa_struct_initializer_signature(out, tstruct);
- out << ";" << endl;
- }
- out << endl;
-
- out << "@end" << endl << endl;
-}
-
-/**
- * Generate signature for initializer of struct with a parameter for
- * each field.
- */
-void t_cocoa_generator::generate_cocoa_struct_initializer_signature(ostream& out,
- t_struct* tstruct) {
- const vector<t_field*>& members = tstruct->get_members();
- vector<t_field*>::const_iterator m_iter;
- indent(out) << "- (instancetype) initWith";
- for (m_iter = members.begin(); m_iter != members.end();) {
- if (m_iter == members.begin()) {
- out << capitalize((*m_iter)->get_name());
- } else {
- out << (*m_iter)->get_name();
- }
- out << ": (" << type_name((*m_iter)->get_type()) << ") " << (*m_iter)->get_name();
- ++m_iter;
- if (m_iter != members.end()) {
- out << " ";
- }
- }
-}
-
-/**
- * Generate the initWithCoder method for this struct so it's compatible with
- * the NSCoding protocol
- */
-void t_cocoa_generator::generate_cocoa_struct_init_with_coder_method(ostream& out,
- t_struct* tstruct,
- bool is_exception) {
-
- indent(out) << "- (instancetype) initWithCoder: (NSCoder *) decoder" << endl;
- scope_up(out);
-
- if (is_exception) {
- // NSExceptions conform to NSCoding, so we can call super
- indent(out) << "self = [super initWithCoder: decoder];" << endl;
- } else {
- indent(out) << "self = [super init];" << endl;
- }
-
- indent(out) << "if (self) ";
- scope_up(out);
-
- const vector<t_field*>& members = tstruct->get_members();
- vector<t_field*>::const_iterator m_iter;
-
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- t_type* t = get_true_type((*m_iter)->get_type());
- out << indent() << "if ([decoder containsValueForKey: @\"" << (*m_iter)->get_name() << "\"])"
- << endl;
- scope_up(out);
- out << indent() << "_" << (*m_iter)->get_name() << " = ";
- if (type_can_be_null(t)) {
- out << "[decoder decodeObjectForKey: @\"" << (*m_iter)->get_name() << "\"];"
- << endl;
- } else if (t->is_enum()) {
- out << "[decoder decodeIntForKey: @\"" << (*m_iter)->get_name() << "\"];" << endl;
- } else {
- t_base_type::t_base tbase = ((t_base_type*)t)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_BOOL:
- out << "[decoder decodeBoolForKey: @\"" << (*m_iter)->get_name() << "\"];" << endl;
- break;
- case t_base_type::TYPE_I8:
- out << "[decoder decodeIntForKey: @\"" << (*m_iter)->get_name() << "\"];" << endl;
- break;
- case t_base_type::TYPE_I16:
- out << "[decoder decodeIntForKey: @\"" << (*m_iter)->get_name() << "\"];" << endl;
- break;
- case t_base_type::TYPE_I32:
- out << "[decoder decodeInt32ForKey: @\"" << (*m_iter)->get_name() << "\"];" << endl;
- break;
- case t_base_type::TYPE_I64:
- out << "[decoder decodeInt64ForKey: @\"" << (*m_iter)->get_name() << "\"];" << endl;
- break;
- case t_base_type::TYPE_DOUBLE:
- out << "[decoder decodeDoubleForKey: @\"" << (*m_iter)->get_name() << "\"];" << endl;
- break;
- default:
- throw "compiler error: don't know how to decode thrift type: "
- + t_base_type::t_base_name(tbase);
- }
- }
- out << indent() << "_" << (*m_iter)->get_name() << "IsSet = YES;" << endl;
- scope_down(out);
- }
-
- scope_down(out);
-
- out << indent() << "return self;" << endl;
- scope_down(out);
- out << endl;
-}
-
-/**
- * Generate the encodeWithCoder method for this struct so it's compatible with
- * the NSCoding protocol
- */
-void t_cocoa_generator::generate_cocoa_struct_encode_with_coder_method(ostream& out,
- t_struct* tstruct,
- bool is_exception) {
-
- indent(out) << "- (void) encodeWithCoder: (NSCoder *) encoder" << endl;
- scope_up(out);
-
- if (is_exception) {
- // NSExceptions conform to NSCoding, so we can call super
- out << indent() << "[super encodeWithCoder: encoder];" << endl;
- }
-
- const vector<t_field*>& members = tstruct->get_members();
- vector<t_field*>::const_iterator m_iter;
-
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- t_type* t = get_true_type((*m_iter)->get_type());
- out << indent() << "if (_" << (*m_iter)->get_name() << "IsSet)" << endl;
- scope_up(out);
- if (type_can_be_null(t)) {
- out << indent() << "[encoder encodeObject: _" << (*m_iter)->get_name() << " forKey: @\""
- << (*m_iter)->get_name() << "\"];" << endl;
- } else if (t->is_enum()) {
- out << indent() << "[encoder encodeInt: _" << (*m_iter)->get_name() << " forKey: @\""
- << (*m_iter)->get_name() << "\"];" << endl;
- } else {
- t_base_type::t_base tbase = ((t_base_type*)t)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_BOOL:
- out << indent() << "[encoder encodeBool: _" << (*m_iter)->get_name() << " forKey: @\""
- << (*m_iter)->get_name() << "\"];" << endl;
- break;
- case t_base_type::TYPE_I8:
- out << indent() << "[encoder encodeInt: _" << (*m_iter)->get_name() << " forKey: @\""
- << (*m_iter)->get_name() << "\"];" << endl;
- break;
- case t_base_type::TYPE_I16:
- out << indent() << "[encoder encodeInt: _" << (*m_iter)->get_name() << " forKey: @\""
- << (*m_iter)->get_name() << "\"];" << endl;
- break;
- case t_base_type::TYPE_I32:
- out << indent() << "[encoder encodeInt32: _" << (*m_iter)->get_name() << " forKey: @\""
- << (*m_iter)->get_name() << "\"];" << endl;
- break;
- case t_base_type::TYPE_I64:
- out << indent() << "[encoder encodeInt64: _" << (*m_iter)->get_name() << " forKey: @\""
- << (*m_iter)->get_name() << "\"];" << endl;
- break;
- case t_base_type::TYPE_DOUBLE:
- out << indent() << "[encoder encodeDouble: _" << (*m_iter)->get_name() << " forKey: @\""
- << (*m_iter)->get_name() << "\"];" << endl;
- break;
- default:
- throw "compiler error: don't know how to encode thrift type: "
- + t_base_type::t_base_name(tbase);
- }
- }
- scope_down(out);
- }
-
- scope_down(out);
- out << endl;
-}
-
-/**
- * Generate the copy method for this struct
- */
-void t_cocoa_generator::generate_cocoa_struct_copy_method(ostream& out, t_struct* tstruct, bool is_exception) {
- out << indent() << "- (instancetype) copyWithZone:(NSZone *)zone" << endl;
- scope_up(out);
-
- if (is_exception) {
- out << indent() << type_name(tstruct) << " val = [" << cocoa_prefix_ << tstruct->get_name() << " errorWithDomain: self.domain code: self.code userInfo: self.userInfo];" << endl;
- } else {
- out << indent() << type_name(tstruct) << " val = [" << cocoa_prefix_ << tstruct->get_name() << " new];" << endl;
- }
-
- const vector<t_field*>& members = tstruct->get_members();
- vector<t_field*>::const_iterator m_iter;
-
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- t_type* t = get_true_type((*m_iter)->get_type());
- out << indent() << "if (_" << (*m_iter)->get_name() << "IsSet)" << endl;
- scope_up(out);
- if (type_can_be_null(t)) {
- out << indent() << "val." << (*m_iter)->get_name() << " = [self." << (*m_iter)->get_name() << " copy];";
- } else {
- out << indent() << "val." << (*m_iter)->get_name() << " = self." << (*m_iter)->get_name() << ";";
- }
- out << endl;
- scope_down(out);
- }
-
- out << indent() << "return val;" << endl;
-
- scope_down(out);
- out << endl;
-}
-
-/**
- * Generate the hash method for this struct
- */
-void t_cocoa_generator::generate_cocoa_struct_hash_method(ostream& out, t_struct* tstruct) {
- indent(out) << "- (NSUInteger) hash" << endl;
- scope_up(out);
- out << indent() << "NSUInteger hash = 17;" << endl;
-
- const vector<t_field*>& members = tstruct->get_members();
- vector<t_field*>::const_iterator m_iter;
-
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- t_type* t = get_true_type((*m_iter)->get_type());
- out << indent() << "hash = (hash * 31) ^ _" << (*m_iter)->get_name()
- << "IsSet ? 2654435761 : 0;" << endl;
- out << indent() << "if (_" << (*m_iter)->get_name() << "IsSet)" << endl;
- scope_up(out);
- if (type_can_be_null(t)) {
- out << indent() << "hash = (hash * 31) ^ [_" << (*m_iter)->get_name() << " hash];" << endl;
- } else {
- out << indent() << "hash = (hash * 31) ^ [@(_" << (*m_iter)->get_name() << ") hash];"
- << endl;
- }
- scope_down(out);
- }
-
- out << indent() << "return hash;" << endl;
- scope_down(out);
- out << endl;
-}
-
-/**
- * Generate the isEqual method for this struct
- */
-void t_cocoa_generator::generate_cocoa_struct_is_equal_method(ostream& out, t_struct* tstruct, bool is_exception) {
- indent(out) << "- (BOOL) isEqual: (id) anObject" << endl;
- scope_up(out);
-
- indent(out) << "if (self == anObject) {" << endl;
- indent_up();
- indent(out) << "return YES;" << endl;
- indent_down();
- indent(out) << "}" << endl;
-
- string class_name = cocoa_prefix_ + tstruct->get_name();
-
- if (is_exception) {
- indent(out) << "if (![super isEqual:anObject]) {" << endl;
- indent_up();
- indent(out) << "return NO;" << endl;
- indent_down();
- indent(out) << "}" << endl << endl;
- }
- else {
- indent(out) << "if (![anObject isKindOfClass:[" << class_name << " class]]) {" << endl;
- indent_up();
- indent(out) << "return NO;" << endl;
- indent_down();
- indent(out) << "}" << endl;
- }
-
- const vector<t_field*>& members = tstruct->get_members();
- vector<t_field*>::const_iterator m_iter;
-
- if (!members.empty()) {
- indent(out) << class_name << " *other = (" << class_name << " *)anObject;" << endl;
-
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- t_type* t = get_true_type((*m_iter)->get_type());
- string name = (*m_iter)->get_name();
- if (type_can_be_null(t)) {
- out << indent() << "if ((_" << name << "IsSet != other->_" << name << "IsSet) ||" << endl
- << indent() << " "
- << "(_" << name << "IsSet && "
- << "((_" << name << " || other->_" << name << ") && "
- << "![_" << name << " isEqual:other->_" << name << "]))) {" << endl;
- } else {
- out << indent() << "if ((_" << name << "IsSet != other->_" << name << "IsSet) ||" << endl
- << indent() << " "
- << "(_" << name << "IsSet && "
- << "(_" << name << " != other->_" << name << "))) {" << endl;
- }
- indent_up();
- indent(out) << "return NO;" << endl;
- indent_down();
- indent(out) << "}" << endl;
- }
- }
-
- out << indent() << "return YES;" << endl;
- scope_down(out);
- out << endl;
-}
-
-/**
- * Generate struct implementation.
- *
- * @param tstruct The struct definition
- * @param is_exception Is this an exception?
- * @param is_result If this is a result it needs a different writer
- */
-void t_cocoa_generator::generate_cocoa_struct_implementation(ostream& out,
- t_struct* tstruct,
- bool is_exception,
- bool is_result) {
- indent(out) << "@implementation " << cocoa_prefix_ << tstruct->get_name() << endl << endl;
-
- const vector<t_field*>& members = tstruct->get_members();
- vector<t_field*>::const_iterator m_iter;
-
- // exceptions need to call the designated initializer on NSException
- if (is_exception) {
- out << indent() << "- (instancetype) init" << endl;
- scope_up(out);
- out << indent() << "return [super initWithDomain: " << cocoa_prefix_ << capitalize(program_name_) << "ErrorDomain" << endl
- << indent() << " code: " << cocoa_prefix_ << capitalize(program_name_) << "Error" << tstruct->get_name() << endl
- << indent() << " userInfo: nil];" << endl;
- scope_down(out);
- out << endl;
- } else {
- // struct
-
- // default initializer
- // setup instance variables with default values
- indent(out) << "- (instancetype) init" << endl;
- scope_up(out);
- indent(out) << "self = [super init];" << endl;
- indent(out) << "if (self)";
- scope_up(out);
- if (members.size() > 0) {
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- t_type* t = get_true_type((*m_iter)->get_type());
- if ((*m_iter)->get_value() != NULL) {
- print_const_value(out,
- "self." + (*m_iter)->get_name(),
- t,
- (*m_iter)->get_value(),
- false);
- }
- }
- }
- scope_down(out);
- indent(out) << "return self;" << endl;
- scope_down(out);
- out << endl;
- }
-
- // initializer with all fields as params
- if (!members.empty()) {
- generate_cocoa_struct_initializer_signature(out, tstruct);
- out << endl;
- scope_up(out);
- if (is_exception) {
- out << indent() << "self = [self init];" << endl;
- } else {
- out << indent() << "self = [super init];" << endl;
- }
-
- indent(out) << "if (self)";
- scope_up(out);
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- out << indent() << "_" << (*m_iter)->get_name() << " = ";
- if (get_true_type((*m_iter)->get_type())->is_container()) {
- out << "[" << (*m_iter)->get_name() << " mutableCopy];" << endl;
- } else {
- out << (*m_iter)->get_name() << ";" << endl;
- }
- out << indent() << "_" << (*m_iter)->get_name() << "IsSet = YES;" << endl;
- }
- scope_down(out);
-
- out << indent() << "return self;" << endl;
- scope_down(out);
- out << endl;
- }
-
- // initWithCoder for NSCoding
- generate_cocoa_struct_init_with_coder_method(out, tstruct, is_exception);
- // encodeWithCoder for NSCoding
- generate_cocoa_struct_encode_with_coder_method(out, tstruct, is_exception);
- // hash and isEqual for NSObject
- generate_cocoa_struct_hash_method(out, tstruct);
- generate_cocoa_struct_is_equal_method(out, tstruct, is_exception);
- // copy for NSObject
- generate_cocoa_struct_copy_method(out, tstruct, is_exception);
-
- // the rest of the methods
- generate_cocoa_struct_field_accessor_implementations(out, tstruct, is_exception);
- generate_cocoa_struct_reader(out, tstruct);
- if (is_result) {
- generate_cocoa_struct_result_writer(out, tstruct);
- } else {
- generate_cocoa_struct_writer(out, tstruct);
- }
- generate_cocoa_struct_validator(out, tstruct);
- generate_cocoa_struct_description(out, tstruct);
-
- out << "@end" << endl << endl;
-}
-
-/**
- * Generates a function to read all the fields of the struct.
- *
- * @param tstruct The struct definition
- */
-void t_cocoa_generator::generate_cocoa_struct_reader(ostream& out, t_struct* tstruct) {
- out << "- (BOOL) read: (id <TProtocol>) inProtocol error: (NSError *__autoreleasing *)__thriftError" << endl;
- scope_up(out);
-
- const vector<t_field*>& fields = tstruct->get_members();
- vector<t_field*>::const_iterator f_iter;
-
- // Declare stack tmp variables
- indent(out) << "NSString * fieldName;" << endl;
- indent(out) << "SInt32 fieldType;" << endl;
- indent(out) << "SInt32 fieldID;" << endl;
- out << endl;
-
- indent(out) << "if (![inProtocol readStructBeginReturningName: NULL error: __thriftError]) return NO;" << endl;
-
- // Loop over reading in fields
- indent(out) << "while (true)" << endl;
- scope_up(out);
-
- // Read beginning field marker
- indent(out)
- << "if (![inProtocol readFieldBeginReturningName: &fieldName type: &fieldType fieldID: &fieldID error: __thriftError]) return NO;"
- << endl;
-
- // Check for field STOP marker and break
- indent(out) << "if (fieldType == TTypeSTOP) { " << endl;
- indent_up();
- indent(out) << "break;" << endl;
- indent_down();
- indent(out) << "}" << endl;
-
- // Switch statement on the field we are reading
- indent(out) << "switch (fieldID)" << endl;
-
- scope_up(out);
-
- // Generate deserialization code for known cases
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- indent(out) << "case " << (*f_iter)->get_key() << ":" << endl;
- indent_up();
- indent(out) << "if (fieldType == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl;
- indent_up();
-
- generate_deserialize_field(out, *f_iter, "fieldValue");
- indent(out) << call_field_setter(*f_iter, "fieldValue") << endl;
-
- indent_down();
- out << indent() << "} else { " << endl;
- if (log_unexpected_) {
- out << indent() << " NSLog(@\"%s: field ID %i has unexpected type %i. Skipping.\", "
- "__PRETTY_FUNCTION__, (int)fieldID, (int)fieldType);" << endl;
- }
-
- out << indent() << " if (![TProtocolUtil skipType: fieldType onProtocol: inProtocol error: __thriftError]) return NO;" << endl;
- out << indent() << "}" << endl << indent() << "break;" << endl;
- indent_down();
- }
-
- // In the default case we skip the field
- out << indent() << "default:" << endl;
- if (log_unexpected_) {
- out << indent() << " NSLog(@\"%s: unexpected field ID %i with type %i. Skipping.\", "
- "__PRETTY_FUNCTION__, (int)fieldID, (int)fieldType);" << endl;
- }
-
- out << indent() << " if (![TProtocolUtil skipType: fieldType onProtocol: inProtocol error: __thriftError]) return NO;" << endl;
-
- out << indent() << " break;" << endl;
-
- scope_down(out);
-
- // Read field end marker
- indent(out) << "if (![inProtocol readFieldEnd: __thriftError]) return NO;" << endl;
-
- scope_down(out);
-
- out << indent() << "if (![inProtocol readStructEnd: __thriftError]) return NO;" << endl;
-
- // performs various checks (e.g. check that all required fields are set)
- if (validate_required_) {
- out << indent() << "if (![self validate: __thriftError]) return NO;" << endl;
- }
-
- indent(out) << "return YES;" << endl;
-
- indent_down();
- out << indent() << "}" << endl << endl;
-}
-
-/**
- * Generates a function to write all the fields of the struct
- *
- * @param tstruct The struct definition
- */
-void t_cocoa_generator::generate_cocoa_struct_writer(ostream& out, t_struct* tstruct) {
- out << indent() << "- (BOOL) write: (id <TProtocol>) outProtocol error: (NSError *__autoreleasing *)__thriftError {" << endl;
- indent_up();
-
- string name = tstruct->get_name();
- const vector<t_field*>& fields = tstruct->get_members();
- vector<t_field*>::const_iterator f_iter;
-
- out << indent() << "if (![outProtocol writeStructBeginWithName: @\"" << name << "\" error: __thriftError]) return NO;" << endl;
-
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- out << indent() << "if (_" << (*f_iter)->get_name() << "IsSet) {" << endl;
- indent_up();
- bool null_allowed = type_can_be_null((*f_iter)->get_type());
- if (null_allowed) {
- out << indent() << "if (_" << (*f_iter)->get_name() << " != nil) {" << endl;
- indent_up();
- }
-
- indent(out) << "if (![outProtocol writeFieldBeginWithName: @\"" << (*f_iter)->get_name()
- << "\" type: " << type_to_enum((*f_iter)->get_type())
- << " fieldID: " << (*f_iter)->get_key() << " error: __thriftError]) return NO;" << endl;
-
- // Write field contents
- generate_serialize_field(out, *f_iter, "_" + (*f_iter)->get_name());
-
- // Write field closer
- indent(out) << "if (![outProtocol writeFieldEnd: __thriftError]) return NO;" << endl;
-
- if (null_allowed) {
- scope_down(out);
- }
- scope_down(out);
- }
- // Write the struct map
- out << indent() << "if (![outProtocol writeFieldStop: __thriftError]) return NO;" << endl
- << indent() << "if (![outProtocol writeStructEnd: __thriftError]) return NO;" << endl;
-
- indent(out) << "return YES;" << endl;
-
- indent_down();
- out << indent() << "}" << endl << endl;
-}
-
-/**
- * Generates a function to write all the fields of the struct, which
- * is a function result. These fields are only written if they are
- * set, and only one of them can be set at a time.
- *
- * @param tstruct The struct definition
- */
-void t_cocoa_generator::generate_cocoa_struct_result_writer(ostream& out, t_struct* tstruct) {
- out << indent() << "- (BOOL) write: (id <TProtocol>) outProtocol error: (NSError *__autoreleasing *)__thriftError {" << endl;
- indent_up();
-
- string name = tstruct->get_name();
- const vector<t_field*>& fields = tstruct->get_members();
- vector<t_field*>::const_iterator f_iter;
-
- out << indent() << "if (![outProtocol writeStructBeginWithName: @\"" << name << "\" error: __thriftError]) return NO;" << endl;
-
- bool first = true;
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- if (first) {
- first = false;
- out << endl << indent() << "if ";
- } else {
- out << " else if ";
- }
-
- out << "(_" << (*f_iter)->get_name() << "IsSet) {" << endl;
- indent_up();
-
- bool null_allowed = type_can_be_null((*f_iter)->get_type());
- if (null_allowed) {
- out << indent() << "if (_" << (*f_iter)->get_name() << " != nil) {" << endl;
- indent_up();
- }
-
- indent(out) << "if (![outProtocol writeFieldBeginWithName: @\"" << (*f_iter)->get_name()
- << "\" type: " << type_to_enum((*f_iter)->get_type())
- << " fieldID: " << (*f_iter)->get_key() << " error: __thriftError]) return NO;" << endl;
-
- // Write field contents
- generate_serialize_field(out, *f_iter, "_" + (*f_iter)->get_name());
-
- // Write field closer
- indent(out) << "if (![outProtocol writeFieldEnd: __thriftError]) return NO;" << endl;
-
- if (null_allowed) {
- indent_down();
- indent(out) << "}" << endl;
- }
-
- indent_down();
- indent(out) << "}";
- }
- // Write the struct map
- out << endl << indent() << "if (![outProtocol writeFieldStop: __thriftError]) return NO;"
- << endl << indent() << "if (![outProtocol writeStructEnd: __thriftError]) return NO;"
- << endl;
-
- indent(out) << "return YES;" << endl;
-
- indent_down();
- out << indent() << "}" << endl << endl;
-}
-
-/**
- * Generates a function to perform various checks
- * (e.g. check that all required fields are set)
- *
- * @param tstruct The struct definition
- */
-void t_cocoa_generator::generate_cocoa_struct_validator(ostream& out, t_struct* tstruct) {
- out << indent() << "- (BOOL) validate: (NSError *__autoreleasing *)__thriftError {" << endl;
- indent_up();
-
- const vector<t_field*>& fields = tstruct->get_members();
- vector<t_field*>::const_iterator f_iter;
-
- out << indent() << "// check for required fields" << endl;
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- t_field* field = (*f_iter);
- if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
- out << indent() << "if (!_" << field->get_name() << "IsSet) ";
- scope_up(out);
- indent(out) << "if (__thriftError) ";
- scope_up(out);
- out << indent() << "*__thriftError = [NSError errorWithDomain: TProtocolErrorDomain" << endl
- << indent() << " code: TProtocolErrorUnknown" << endl
- << indent() << " userInfo: @{TProtocolErrorExtendedErrorKey: @(TProtocolExtendedErrorMissingRequiredField)," << endl
- << indent() << " TProtocolErrorFieldNameKey: @\"" << (*f_iter)->get_name() << "\"}];" << endl;
- scope_down(out);
- scope_down(out);
- }
- }
- indent(out) << "return YES;" << endl;
- indent_down();
- out << indent() << "}" << endl << endl;
-}
-
-/**
- * Generate property accessor methods for all fields in the struct.
- * getter, setter, isset getter.
- *
- * @param tstruct The struct definition
- */
-void t_cocoa_generator::generate_cocoa_struct_field_accessor_implementations(ostream& out,
- t_struct* tstruct,
- bool is_exception) {
- (void)is_exception;
- const vector<t_field*>& fields = tstruct->get_members();
- vector<t_field*>::const_iterator f_iter;
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- t_field* field = *f_iter;
- t_type* type = get_true_type(field->get_type());
- std::string field_name = field->get_name();
- std::string cap_name = field_name;
- cap_name[0] = toupper(cap_name[0]);
-
- // Simple setter
- indent(out) << "- (void) set" << cap_name << ": (" << type_name(type, false, true) << ") " << field_name
- << " {" << endl;
- indent_up();
- indent(out) << "_" << field_name << " = " << field_name << ";" << endl;
- indent(out) << "_" << field_name << "IsSet = YES;" << endl;
- indent_down();
- indent(out) << "}" << endl << endl;
-
- // Unsetter - do we need this?
- indent(out) << "- (void) unset" << cap_name << " {" << endl;
- indent_up();
- if (type_can_be_null(type)) {
- indent(out) << "_" << field_name << " = nil;" << endl;
- }
- indent(out) << "_" << field_name << "IsSet = NO;" << endl;
- indent_down();
- indent(out) << "}" << endl << endl;
- }
-}
-
-/**
- * Generates a description method for the given struct
- *
- * @param tstruct The struct definition
- */
-void t_cocoa_generator::generate_cocoa_struct_description(ostream& out, t_struct* tstruct) {
-
- // Allow use of debugDescription so the app can add description via a cateogory/extension
- if (debug_descriptions_) {
- out << indent() << "- (NSString *) debugDescription {" << endl;
- }
- else {
- out << indent() << "- (NSString *) description {" << endl;
- }
- indent_up();
-
- out << indent() << "NSMutableString * ms = [NSMutableString stringWithString: @\""
- << cocoa_prefix_ << tstruct->get_name() << "(\"];" << endl;
-
- const vector<t_field*>& fields = tstruct->get_members();
- vector<t_field*>::const_iterator f_iter;
- bool first = true;
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- if (first) {
- first = false;
- indent(out) << "[ms appendString: @\"" << (*f_iter)->get_name() << ":\"];" << endl;
- } else {
- indent(out) << "[ms appendString: @\"," << (*f_iter)->get_name() << ":\"];" << endl;
- }
- t_type* ttype = (*f_iter)->get_type();
- indent(out) << "[ms appendFormat: @\"" << format_string_for_type(ttype) << "\", "
- << format_cast_for_type(ttype) << "_" << (*f_iter)->get_name() << "];" << endl;
- }
- out << indent() << "[ms appendString: @\")\"];" << endl << indent()
- << "return [NSString stringWithString: ms];" << endl;
-
- indent_down();
- indent(out) << "}" << endl << endl;
-}
-
-/**
- * Generates a thrift service. In Objective-C this consists of a
- * protocol definition, a client interface and a client implementation.
- *
- * @param tservice The service definition
- */
-void t_cocoa_generator::generate_service(t_service* tservice) {
- generate_cocoa_service_protocol(f_header_, tservice);
- generate_cocoa_service_client_interface(f_header_, tservice);
- generate_cocoa_service_server_interface(f_header_, tservice);
- generate_cocoa_service_helpers(tservice);
- generate_cocoa_service_client_implementation(f_impl_, tservice);
- generate_cocoa_service_server_implementation(f_impl_, tservice);
- if (async_clients_) {
- generate_cocoa_service_async_protocol(f_header_, tservice);
- generate_cocoa_service_client_async_interface(f_header_, tservice);
- generate_cocoa_service_client_async_implementation(f_impl_, tservice);
- }
-}
-
-/**
- * Generates structs for all the service return types
- *
- * @param tservice The service
- */
-void t_cocoa_generator::generate_cocoa_service_helpers(t_service* tservice) {
- vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::iterator f_iter;
- for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-
- t_struct* ts = (*f_iter)->get_arglist();
-
- string qname = function_args_helper_struct_type(tservice, *f_iter);
-
- t_struct qname_ts = t_struct(ts->get_program(), qname);
-
- const vector<t_field*>& members = ts->get_members();
- vector<t_field*>::const_iterator m_iter;
- for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- qname_ts.append(*m_iter);
- }
-
- generate_cocoa_struct_interface(f_impl_, &qname_ts, false);
- generate_cocoa_struct_implementation(f_impl_, &qname_ts, false, false);
- generate_function_helpers(tservice, *f_iter);
- }
-}
-
-string t_cocoa_generator::function_result_helper_struct_type(t_service *tservice, t_function* tfunction) {
- if (tfunction->is_oneway()) {
- return tservice->get_name() + "_" + tfunction->get_name();
- } else {
- return tservice->get_name() + "_" + tfunction->get_name() + "_result";
- }
-}
-
-string t_cocoa_generator::function_args_helper_struct_type(t_service *tservice, t_function* tfunction) {
- return tservice->get_name() + "_" + tfunction->get_name() + "_args";
-}
-
-/**
- * Generates a struct and helpers for a function.
- *
- * @param tfunction The function
- */
-void t_cocoa_generator::generate_function_helpers(t_service *tservice, t_function* tfunction) {
- if (tfunction->is_oneway()) {
- return;
- }
-
- // create a result struct with a success field of the return type,
- // and a field for each type of exception thrown
- t_struct result(program_, function_result_helper_struct_type(tservice, tfunction));
- t_field success(tfunction->get_returntype(), "success", 0);
- if (!tfunction->get_returntype()->is_void()) {
- result.append(&success);
- }
-
- t_struct* xs = tfunction->get_xceptions();
- const vector<t_field*>& fields = xs->get_members();
- vector<t_field*>::const_iterator f_iter;
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- result.append(*f_iter);
- }
-
- // generate the result struct
- generate_cocoa_struct_interface(f_impl_, &result, false);
- generate_cocoa_struct_implementation(f_impl_, &result, false, true);
-}
-
-/**
- * Generates a service protocol definition.
- *
- * @param tservice The service to generate a protocol definition for
- */
-void t_cocoa_generator::generate_cocoa_service_protocol(ostream& out, t_service* tservice) {
- out << "@protocol " << cocoa_prefix_ << tservice->get_name() << " <NSObject>" << endl;
-
- vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::iterator f_iter;
- for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
- out << "- " << function_signature(*f_iter, true) << ";"
- << " // throws ";
- t_struct* xs = (*f_iter)->get_xceptions();
- const std::vector<t_field*>& xceptions = xs->get_members();
- vector<t_field*>::const_iterator x_iter;
- for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
- out << type_name((*x_iter)->get_type()) + ", ";
- }
- out << "TException" << endl;
- }
- out << "@end" << endl << endl;
-}
-
-/**
- * Generates an asynchronous service protocol definition.
- *
- * @param tservice The service to generate a protocol definition for
- */
-void t_cocoa_generator::generate_cocoa_service_async_protocol(ostream& out, t_service* tservice) {
- out << "@protocol " << cocoa_prefix_ << tservice->get_name() << "Async"
- << " <NSObject>" << endl;
-
- vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::iterator f_iter;
- for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
- out << "- " << async_function_signature(*f_iter, false) << ";" << endl;
- if (promise_kit_) {
- out << "- " << promise_function_signature(*f_iter) << ";" << endl;
- }
- }
- out << "@end" << endl << endl;
-}
-
-/**
- * Generates a service client interface definition.
- *
- * @param tservice The service to generate a client interface definition for
- */
-void t_cocoa_generator::generate_cocoa_service_client_interface(ostream& out,
- t_service* tservice) {
- out << "@interface " << cocoa_prefix_ << tservice->get_name() << "Client : TBaseClient <"
- << cocoa_prefix_ << tservice->get_name() << "> " << endl;
-
- out << "- (id) initWithProtocol: (id <TProtocol>) protocol;" << endl;
- out << "- (id) initWithInProtocol: (id <TProtocol>) inProtocol outProtocol: (id <TProtocol>) "
- "outProtocol;" << endl;
- out << "@end" << endl << endl;
-}
-
-/**
- * Generates a service client interface definition.
- *
- * @param tservice The service to generate a client interface definition for
- */
-void t_cocoa_generator::generate_cocoa_service_client_async_interface(ostream& out,
- t_service* tservice) {
- out << "@interface " << cocoa_prefix_ << tservice->get_name() << "ClientAsync : TBaseClient <"
- << cocoa_prefix_ << tservice->get_name() << "Async> " << endl
- << endl;
-
- out << "- (id) initWithProtocolFactory: (id <TProtocolFactory>) protocolFactory "
- << "transportFactory: (id <TAsyncTransportFactory>) transportFactory;" << endl;
- out << "@end" << endl << endl;
-}
-
-/**
- * Generates a service server interface definition. In other words, the TProcess implementation for
- *the
- * service definition.
- *
- * @param tservice The service to generate a client interface definition for
- */
-void t_cocoa_generator::generate_cocoa_service_server_interface(ostream& out,
- t_service* tservice) {
- out << "@interface " << cocoa_prefix_ << tservice->get_name()
- << "Processor : NSObject <TProcessor> " << endl;
-
- out << "- (id) initWith" << tservice->get_name() << ": (id <" << cocoa_prefix_
- << tservice->get_name() << ">) service;" << endl;
- out << "- (id<" << cocoa_prefix_ << tservice->get_name() << ">) service;" << endl;
-
- out << "@end" << endl << endl;
-}
-
-void t_cocoa_generator::generate_cocoa_service_client_send_function_implementation(
- ostream& out,
- t_service *tservice,
- t_function* tfunction,
- bool needs_protocol) {
- string funname = tfunction->get_name();
-
- t_function send_function(g_type_bool,
- string("send_") + tfunction->get_name(),
- tfunction->get_arglist());
-
- string argsname = function_args_helper_struct_type(tservice, tfunction);
-
- // Open function
- indent(out) << "- (BOOL) send_" << tfunction->get_name() << argument_list(tfunction->get_arglist(), needs_protocol ? "outProtocol" : "", true) << endl;
- scope_up(out);
-
- // Serialize the request
- out << indent() << "if (![outProtocol writeMessageBeginWithName: @\"" << funname << "\""
- << (tfunction->is_oneway() ? " type: TMessageTypeONEWAY" : " type: TMessageTypeCALL")
- << " sequenceID: 0 error: __thriftError]) return NO;" << endl;
-
- out << indent() << "if (![outProtocol writeStructBeginWithName: @\"" << argsname
- << "\" error: __thriftError]) return NO;" << endl;
-
- // write out function parameters
- t_struct* arg_struct = tfunction->get_arglist();
- const vector<t_field*>& fields = arg_struct->get_members();
- vector<t_field*>::const_iterator fld_iter;
- for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
- string fieldName = (*fld_iter)->get_name();
- if (type_can_be_null((*fld_iter)->get_type())) {
- out << indent() << "if (" << fieldName << " != nil)";
- scope_up(out);
- }
- out << indent() << "if (![outProtocol writeFieldBeginWithName: @\"" << fieldName
- << "\""
- " type: " << type_to_enum((*fld_iter)->get_type())
- << " fieldID: " << (*fld_iter)->get_key() << " error: __thriftError]) return NO;" << endl;
-
- generate_serialize_field(out, *fld_iter, fieldName);
-
- out << indent() << "if (![outProtocol writeFieldEnd: __thriftError]) return NO;" << endl;
-
- if (type_can_be_null((*fld_iter)->get_type())) {
- indent_down();
- out << indent() << "}" << endl;
- }
- }
-
- out << indent() << "if (![outProtocol writeFieldStop: __thriftError]) return NO;" << endl;
- out << indent() << "if (![outProtocol writeStructEnd: __thriftError]) return NO;" << endl;
- out << indent() << "if (![outProtocol writeMessageEnd: __thriftError]) return NO;" << endl;
- out << indent() << "return YES;" << endl;
- scope_down(out);
- out << endl;
-}
-
-void t_cocoa_generator::generate_cocoa_service_client_recv_function_implementation(
- ostream& out,
- t_service* tservice,
- t_function* tfunction,
- bool needs_protocol) {
-
-
- // Open function
- indent(out) << "- (BOOL) recv_" << tfunction->get_name();
- if (!tfunction->get_returntype()->is_void()) {
- out << ": (" << type_name(tfunction->get_returntype(), false, true) << " *) result ";
- if (needs_protocol) {
- out << "protocol";
- } else {
- out << "error";
- }
- }
- if (needs_protocol) {
- out << ": (id<TProtocol>) inProtocol error";
- }
- out << ": (NSError *__autoreleasing *)__thriftError" << endl;
- scope_up(out);
-
- // TODO(mcslee): Message validation here, was the seqid etc ok?
-
- // check for an exception
- out << indent() << "NSError *incomingException = [self checkIncomingMessageException: inProtocol];" << endl
- << indent() << "if (incomingException)";
- scope_up(out);
- out << indent() << "if (__thriftError)";
- scope_up(out);
- out << indent() << "*__thriftError = incomingException;" << endl;
- scope_down(out);
- out << indent() << "return NO;" << endl;
- scope_down(out);
-
- // FIXME - could optimize here to reduce creation of temporary objects.
- string resultname = function_result_helper_struct_type(tservice, tfunction);
- out << indent() << cocoa_prefix_ << resultname << " * resulter = [" << cocoa_prefix_ << resultname << " new];" << endl;
- indent(out) << "if (![resulter read: inProtocol error: __thriftError]) return NO;" << endl;
- indent(out) << "if (![inProtocol readMessageEnd: __thriftError]) return NO;" << endl;
-
- // Careful, only return _result if not a void function
- if (!tfunction->get_returntype()->is_void()) {
- out << indent() << "if (resulter.successIsSet)";
- scope_up(out);
- out << indent() << "*result = resulter.success;" << endl;
- out << indent() << "return YES;" << endl;
- scope_down(out);
- }
-
- t_struct* xs = tfunction->get_xceptions();
- const std::vector<t_field*>& xceptions = xs->get_members();
- vector<t_field*>::const_iterator x_iter;
- for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
- out << indent() << "if (resulter." << (*x_iter)->get_name() << "IsSet)";
- scope_up(out);
- out << indent() << "if (__thriftError)";
- scope_up(out);
- out << indent() << "*__thriftError = [resulter " << (*x_iter)->get_name() << "];" << endl;
- scope_down(out);
- out << indent() << "return NO;" << endl;
- scope_down(out);
- }
-
- // If you get here it's an exception, unless a void function
- if (tfunction->get_returntype()->is_void()) {
- indent(out) << "return YES;" << endl;
- } else {
- out << indent() << "if (__thriftError)";
- scope_up(out);
- out << indent() << "*__thriftError = [NSError errorWithDomain: TApplicationErrorDomain" << endl
- << indent() << " code: TApplicationErrorMissingResult" << endl
- << indent() << " userInfo: @{TApplicationErrorMethodKey: @\""
- << tfunction->get_name() << "\"}];" << endl;
- scope_down(out);
- out << indent() << "return NO;" << endl;
- }
-
- // Close function
- scope_down(out);
- out << endl;
-}
-
-/**
- * Generates an invocation of a given 'send_' function.
- *
- * @param tfunction The service to generate an implementation for
- */
-void t_cocoa_generator::generate_cocoa_service_client_send_function_invocation(
- ostream& out,
- t_function* tfunction) {
-
- t_struct* arg_struct = tfunction->get_arglist();
- const vector<t_field*>& fields = arg_struct->get_members();
- vector<t_field*>::const_iterator fld_iter;
- out << indent() << "if (![self send_" << tfunction->get_name();
- bool first = true;
- for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
- string fieldName = (*fld_iter)->get_name();
- out << " ";
- if (first) {
- first = false;
- out << ": " << fieldName;
- } else {
- out << fieldName << ": " << fieldName;
- }
- }
- if (!fields.empty()) {
- out << " error";
- }
- out << ": __thriftError]) " << invalid_return_statement(tfunction) << endl;
-}
-
-/**
- * Generates an invocation of a given 'send_' function.
- *
- * @param tfunction The service to generate an implementation for
- */
-void t_cocoa_generator::generate_cocoa_service_client_send_async_function_invocation(
- ostream& out,
- t_function* tfunction,
- string failureBlockName) {
-
- t_struct* arg_struct = tfunction->get_arglist();
- const vector<t_field*>& fields = arg_struct->get_members();
- vector<t_field*>::const_iterator fld_iter;
- out << indent() << "if (![self send_" << tfunction->get_name();
- bool first = true;
- for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
- string fieldName = (*fld_iter)->get_name();
- out << " ";
- if (first) {
- first = false;
- out << ": " << fieldName;
- } else {
- out << fieldName << ": " << fieldName;
- }
- }
- if (!fields.empty()) {
- out << " protocol";
- }
- out << ": protocol error: &thriftError]) ";
- scope_up(out);
- out << indent() << failureBlockName << "(thriftError);" << endl
- << indent() << "return;" << endl;
- scope_down(out);
-}
-
-/**
- * Generates a service client implementation.
- *
- * @param tservice The service to generate an implementation for
- */
-void t_cocoa_generator::generate_cocoa_service_client_implementation(ostream& out,
- t_service* tservice) {
-
- string name = cocoa_prefix_ + tservice->get_name() + "Client";
-
- out << "@interface " << name << " () ";
- scope_up(out);
- out << endl;
- out << indent() << "id<TProtocol> inProtocol;" << endl;
- out << indent() << "id<TProtocol> outProtocol;" << endl;
- out << endl;
- scope_down(out);
- out << endl;
- out << "@end" << endl << endl;
-
- out << "@implementation " << name << endl;
-
- // initializers
- out << "- (id) initWithProtocol: (id <TProtocol>) protocol" << endl;
- scope_up(out);
- out << indent() << "return [self initWithInProtocol: protocol outProtocol: protocol];" << endl;
- scope_down(out);
- out << endl;
-
- out << "- (id) initWithInProtocol: (id <TProtocol>) anInProtocol outProtocol: (id <TProtocol>) "
- "anOutProtocol" << endl;
- scope_up(out);
- out << indent() << "self = [super init];" << endl;
- out << indent() << "if (self) ";
- scope_up(out);
- out << indent() << "inProtocol = anInProtocol;" << endl;
- out << indent() << "outProtocol = anOutProtocol;" << endl;
- scope_down(out);
- out << indent() << "return self;" << endl;
- scope_down(out);
- out << endl;
-
- // generate client method implementations
- vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::const_iterator f_iter;
- for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-
- generate_cocoa_service_client_send_function_implementation(out, tservice, *f_iter, false);
-
- if (!(*f_iter)->is_oneway()) {
- generate_cocoa_service_client_recv_function_implementation(out, tservice, *f_iter, false);
- }
-
- // Open function
- indent(out) << "- " << function_signature(*f_iter, true) << endl;
- scope_up(out);
- generate_cocoa_service_client_send_function_invocation(out, *f_iter);
-
- out << indent() << "if (![[outProtocol transport] flush: __thriftError]) " << invalid_return_statement(*f_iter) << endl;
- if (!(*f_iter)->is_oneway()) {
- if ((*f_iter)->get_returntype()->is_void()) {
- out << indent() << "if (![self recv_" << (*f_iter)->get_name() << ": __thriftError]) return NO;" << endl;
- out << indent() << "return YES;" << endl;
- } else {
- out << indent() << type_name((*f_iter)->get_returntype(), false, true) << " __result;" << endl
- << indent() << "if (![self recv_" << (*f_iter)->get_name() << ": &__result error: __thriftError]) "
- << invalid_return_statement(*f_iter) << endl;
- if (type_can_be_null((*f_iter)->get_returntype())) {
- out << indent() << "return __result;" << endl;
- } else {
- out << indent() << "return @(__result);" << endl;
- }
- }
- }
- else {
- out << indent() << "return YES;" << endl;
- }
- scope_down(out);
- out << endl;
- }
-
- out << "@end" << endl << endl;
-}
-
-/**
- * Generates a service client implementation for its asynchronous interface.
- *
- * @param tservice The service to generate an implementation for
- */
-void t_cocoa_generator::generate_cocoa_service_client_async_implementation(ostream& out,
- t_service* tservice) {
-
- string name = cocoa_prefix_ + tservice->get_name() + "ClientAsync";
-
- out << "@interface " << name << " () ";
- scope_up(out);
- out << endl;
- out << indent() << "id<TProtocolFactory> protocolFactory;" << endl;
- out << indent() << "id<TAsyncTransportFactory> transportFactory;" << endl;
- out << endl;
- scope_down(out);
- out << endl;
- out << "@end" << endl << endl;
-
-
- out << "@implementation " << name << endl
- << endl << "- (id) initWithProtocolFactory: (id <TProtocolFactory>) aProtocolFactory "
- "transportFactory: (id <TAsyncTransportFactory>) aTransportFactory;" << endl;
-
- scope_up(out);
- out << indent() << "self = [super init];" << endl;
- out << indent() << "if (self) {" << endl;
- out << indent() << " protocolFactory = aProtocolFactory;" << endl;
- out << indent() << " transportFactory = aTransportFactory;" << endl;
- out << indent() << "}" << endl;
- out << indent() << "return self;" << endl;
- scope_down(out);
- out << endl;
-
- // generate client method implementations
- vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::const_iterator f_iter;
- for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-
- generate_cocoa_service_client_send_function_implementation(out, tservice, *f_iter, true);
-
- if (!(*f_iter)->is_oneway()) {
- generate_cocoa_service_client_recv_function_implementation(out, tservice, *f_iter, true);
- }
-
- // Open function
- indent(out) << "- " << async_function_signature(*f_iter, false) << endl;
- scope_up(out);
-
- out << indent() << "NSError *thriftError;" << endl
- << indent() << "id<TAsyncTransport> transport = [transportFactory newTransport];" << endl
- << indent() << "id<TProtocol> protocol = [protocolFactory newProtocolOnTransport:transport];" << endl
- << endl;
-
- generate_cocoa_service_client_send_async_function_invocation(out, *f_iter, "failureBlock");
-
- out << indent() << "[transport flushWithCompletion:^{" << endl;
- indent_up();
-
- if (!(*f_iter)->is_oneway()) {
- out << indent() << "NSError *thriftError;" << endl;
-
- if (!(*f_iter)->get_returntype()->is_void()) {
- out << indent() << type_name((*f_iter)->get_returntype()) << " result;" << endl;
- }
- out << indent() << "if (![self recv_" << (*f_iter)->get_name();
- if (!(*f_iter)->get_returntype()->is_void()) {
- out << ": &result protocol";
- }
- out << ": protocol error: &thriftError]) ";
- scope_up(out);
- out << indent() << "failureBlock(thriftError);" << endl
- << indent() << "return;" << endl;
- scope_down(out);
- }
-
- out << indent() << "responseBlock(";
- if (!(*f_iter)->is_oneway() && !(*f_iter)->get_returntype()->is_void()) {
- out << "result";
- }
- out << ");" << endl;
-
- indent_down();
-
- out << indent() << "} failure:failureBlock];" << endl;
-
- scope_down(out);
-
- out << endl;
-
- // Promise function
- if (promise_kit_) {
-
- indent(out) << "- " << promise_function_signature(*f_iter) << endl;
- scope_up(out);
-
- out << indent() << "return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolver) {" << endl;
- indent_up();
-
- out << indent() << "NSError *thriftError;" << endl
- << indent() << "id<TAsyncTransport> transport = [transportFactory newTransport];" << endl
- << indent() << "id<TProtocol> protocol = [protocolFactory newProtocolOnTransport:transport];" << endl
- << endl;
-
- generate_cocoa_service_client_send_async_function_invocation(out, *f_iter, "resolver");
-
- out << indent() << "[transport flushWithCompletion:^{" << endl;
- indent_up();
-
- if (!(*f_iter)->is_oneway()) {
- out << indent() << "NSError *thriftError;" << endl;
-
- if (!(*f_iter)->get_returntype()->is_void()) {
- out << indent() << type_name((*f_iter)->get_returntype()) << " result;" << endl;
- }
- out << indent() << "if (![self recv_" << (*f_iter)->get_name();
- if (!(*f_iter)->get_returntype()->is_void()) {
- out << ": &result protocol";
- }
- out << ": protocol error: &thriftError]) ";
- scope_up(out);
- out << indent() << "resolver(thriftError);" << endl
- << indent() << "return;" << endl;
- scope_down(out);
- }
-
- out << indent() << "resolver(";
- if ((*f_iter)->is_oneway() || (*f_iter)->get_returntype()->is_void()) {
- out << "@YES";
- } else if (type_can_be_null((*f_iter)->get_returntype())) {
- out << "result";
- } else {
- out << "@(result)";
- }
- out << ");" << endl;
-
- indent_down();
-
- out << indent() << "} failure:^(NSError *error) {" << endl;
- indent_up();
- out << indent() << "resolver(error);" << endl;
- indent_down();
- out << indent() << "}];" << endl;
-
- indent_down();
- out << indent() << "}];" << endl;
-
- scope_down(out);
-
- out << endl;
-
- }
-
- }
-
- out << "@end" << endl << endl;
-}
-
-/**
- * Generates a service server implementation. In other words the actual TProcessor implementation
- * for the service.
- *
- * @param tservice The service to generate an implementation for
- */
-void t_cocoa_generator::generate_cocoa_service_server_implementation(ostream& out,
- t_service* tservice) {
-
- string name = cocoa_prefix_ + tservice->get_name() + "Processor";
-
- out << "@interface " << name << " () ";
-
- scope_up(out);
- out << indent() << "id <" << cocoa_prefix_ << tservice->get_name() << "> service;" << endl;
- out << indent() << "NSDictionary * methodMap;" << endl;
- scope_down(out);
-
- out << "@end" << endl << endl;
-
- out << "@implementation " << name << endl;
-
- // initializer
- out << endl;
- out << "- (id) initWith" << tservice->get_name() << ": (id <" << cocoa_prefix_ << tservice->get_name() << ">) aService" << endl;
- scope_up(out);
- out << indent() << "self = [super init];" << endl;
- out << indent() << "if (self) ";
- scope_up(out);
- out << indent() << "service = aService;" << endl;
- out << indent() << "methodMap = [NSMutableDictionary dictionary];" << endl;
-
- // generate method map for routing incoming calls
- vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::const_iterator f_iter;
- for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
- string funname = (*f_iter)->get_name();
- scope_up(out);
- out << indent() << "SEL s = @selector(process_" << funname << "_withSequenceID:inProtocol:outProtocol:error:);" << endl;
- out << indent() << "NSMethodSignature * sig = [self methodSignatureForSelector: s];" << endl;
- out << indent() << "NSInvocation * invocation = [NSInvocation invocationWithMethodSignature: sig];" << endl;
- out << indent() << "[invocation setSelector: s];" << endl;
- out << indent() << "[invocation retainArguments];" << endl;
- out << indent() << "[methodMap setValue: invocation forKey: @\"" << funname << "\"];" << endl;
- scope_down(out);
- }
- scope_down(out);
- out << indent() << "return self;" << endl;
- scope_down(out);
-
- // implementation of the 'service' method which returns the service associated with this
- // processor
- out << endl;
- out << indent() << "- (id<" << cocoa_prefix_ << tservice->get_name() << ">) service" << endl;
- out << indent() << "{" << endl;
- out << indent() << " return service;" << endl;
- out << indent() << "}" << endl;
-
- // implementation of the TProcess method, which dispatches the incoming call using the method map
- out << endl;
- out << indent() << "- (BOOL) processOnInputProtocol: (id <TProtocol>) inProtocol" << endl;
- out << indent() << " outputProtocol: (id <TProtocol>) outProtocol" << endl;
- out << indent() << " error: (NSError *__autoreleasing *)__thriftError" << endl;
- out << indent() << "{" << endl;
- out << indent() << " NSString * messageName;" << endl;
- out << indent() << " SInt32 messageType;" << endl;
- out << indent() << " SInt32 seqID;" << endl;
- out << indent() << " if (![inProtocol readMessageBeginReturningName: &messageName" << endl;
- out << indent() << " type: &messageType" << endl;
- out << indent() << " sequenceID: &seqID" << endl;
- out << indent() << " error: __thriftError]) return NO;" << endl;
- out << indent() << " NSInvocation * invocation = [methodMap valueForKey: messageName];" << endl;
- out << indent() << " if (invocation == nil) {" << endl;
- out << indent() << " if (![TProtocolUtil skipType: TTypeSTRUCT onProtocol: inProtocol error: __thriftError]) return NO;" << endl;
- out << indent() << " if (![inProtocol readMessageEnd: __thriftError]) return NO;" << endl;
- out << indent() << " NSError * x = [NSError errorWithDomain: TApplicationErrorDomain" << endl;
- out << indent() << " code: TApplicationErrorUnknownMethod" << endl;
- out << indent() << " userInfo: @{TApplicationErrorMethodKey: messageName}];" << endl;
- out << indent() << " if (![outProtocol writeMessageBeginWithName: messageName" << endl;
- out << indent() << " type: TMessageTypeEXCEPTION" << endl;
- out << indent() << " sequenceID: seqID" << endl;
- out << indent() << " error: __thriftError]) return NO;" << endl;
- out << indent() << " if (![x write: outProtocol error: __thriftError]) return NO;" << endl;
- out << indent() << " if (![outProtocol writeMessageEnd: __thriftError]) return NO;" << endl;
- out << indent() << " if (![[outProtocol transport] flush: __thriftError]) return NO;" << endl;
- out << indent() << " return YES;" << endl;
- out << indent() << " }" << endl;
- out << indent() << " // NSInvocation does not conform to NSCopying protocol" << endl;
- out << indent() << " NSInvocation * i = [NSInvocation invocationWithMethodSignature: "
- "[invocation methodSignature]];" << endl;
- out << indent() << " [i setSelector: [invocation selector]];" << endl;
- out << indent() << " [i setArgument: &seqID atIndex: 2];" << endl;
- out << indent() << " [i setArgument: &inProtocol atIndex: 3];" << endl;
- out << indent() << " [i setArgument: &outProtocol atIndex: 4];" << endl;
- out << indent() << " [i setArgument: &__thriftError atIndex: 5];" << endl;
- out << indent() << " [i setTarget: self];" << endl;
- out << indent() << " [i invoke];" << endl;
- out << indent() << " return YES;" << endl;
- out << indent() << "}" << endl;
-
- // generate a process_XXXX method for each service function, which reads args, calls the service,
- // and writes results
- functions = tservice->get_functions();
- for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
- out << endl;
- string funname = (*f_iter)->get_name();
- out << indent() << "- (BOOL) process_" << funname
- << "_withSequenceID: (SInt32) seqID inProtocol: (id<TProtocol>) inProtocol outProtocol: "
- "(id<TProtocol>) outProtocol error:(NSError *__autoreleasing *)__thriftError" << endl;
- scope_up(out);
- string argstype = cocoa_prefix_ + function_args_helper_struct_type(tservice, *f_iter);
- out << indent() << argstype << " * args = [" << argstype << " new];" << endl;
- out << indent() << "if (![args read: inProtocol error: __thriftError]) return NO;" << endl;
- out << indent() << "if (![inProtocol readMessageEnd: __thriftError]) return NO;" << endl;
-
- // prepare the result if not oneway
- if (!(*f_iter)->is_oneway()) {
- string resulttype = cocoa_prefix_ + function_result_helper_struct_type(tservice, *f_iter);
- out << indent() << resulttype << " * result = [" << resulttype << " new];" << endl;
- }
-
- // make the call to the actual service object
- out << indent();
- if ((*f_iter)->get_returntype()->is_void()) {
- out << "BOOL";
- } else if (type_can_be_null((*f_iter)->get_returntype())) {
- out << type_name((*f_iter)->get_returntype(), false, true);
- } else {
- out << "NSNumber *";
- }
- out << " serviceResult = ";
- if ((*f_iter)->get_returntype()->get_true_type()->is_container()) {
- out << "(" << type_name((*f_iter)->get_returntype(), false, true) << ")";
- }
- out << "[service " << funname;
- // supplying arguments
- t_struct* arg_struct = (*f_iter)->get_arglist();
- const vector<t_field*>& fields = arg_struct->get_members();
- vector<t_field*>::const_iterator fld_iter;
- bool first = true;
- for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
- string fieldName = (*fld_iter)->get_name();
- if (first) {
- first = false;
- out << ": [args " << fieldName << "]";
- } else {
- out << " " << fieldName << ": [args " << fieldName << "]";
- }
- }
- if (!fields.empty()) {
- out << " error";
- }
- out << ": __thriftError];" << endl;
- out << indent() << "if (!serviceResult) return NO;" << endl;
- if (!(*f_iter)->get_returntype()->is_void()) {
- out << indent() << "[result setSuccess: " << unbox((*f_iter)->get_returntype(), "serviceResult") << "];" << endl;
- }
-
- // write out the result if not oneway
- if (!(*f_iter)->is_oneway()) {
- out << indent() << "if (![outProtocol writeMessageBeginWithName: @\"" << funname << "\"" << endl;
- out << indent() << " type: TMessageTypeREPLY" << endl;
- out << indent() << " sequenceID: seqID" << endl;
- out << indent() << " error: __thriftError]) return NO;" << endl;
- out << indent() << "if (![result write: outProtocol error: __thriftError]) return NO;" << endl;
- out << indent() << "if (![outProtocol writeMessageEnd: __thriftError]) return NO;" << endl;
- out << indent() << "if (![[outProtocol transport] flush: __thriftError]) return NO;" << endl;
- }
- out << indent() << "return YES;" << endl;
-
- scope_down(out);
- }
-
- out << "@end" << endl << endl;
-}
-
-/**
- * Deserializes a field of any type.
- *
- * @param tfield The field
- * @param fieldName The variable name for this field
- */
-void t_cocoa_generator::generate_deserialize_field(ostream& out,
- t_field* tfield,
- string fieldName) {
- t_type* type = get_true_type(tfield->get_type());
-
- if (type->is_void()) {
- throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " + tfield->get_name();
- }
-
- if (type->is_struct() || type->is_xception()) {
- generate_deserialize_struct(out, (t_struct*)type, fieldName);
- } else if (type->is_container()) {
- generate_deserialize_container(out, type, fieldName);
- } else if (type->is_base_type() || type->is_enum()) {
- indent(out) << type_name(type) << " " << fieldName << ";" << endl;
- indent(out) << "if (![inProtocol ";
-
- if (type->is_base_type()) {
- t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_VOID:
- throw "compiler error: cannot serialize void field in a struct: " + tfield->get_name();
- break;
- case t_base_type::TYPE_STRING:
- if (type->is_binary()) {
- out << "readBinary:&" << fieldName << " error: __thriftError]";
- } else {
- out << "readString:&" << fieldName << " error: __thriftError]";
- }
- break;
- case t_base_type::TYPE_BOOL:
- out << "readBool:&" << fieldName << " error: __thriftError]";
- break;
- case t_base_type::TYPE_I8:
- out << "readByte:(UInt8 *)&" << fieldName << " error: __thriftError]";
- break;
- case t_base_type::TYPE_I16:
- out << "readI16:&" << fieldName << " error: __thriftError]";
- break;
- case t_base_type::TYPE_I32:
- out << "readI32:&" << fieldName << " error: __thriftError]";
- break;
- case t_base_type::TYPE_I64:
- out << "readI64:&" << fieldName << " error: __thriftError]";
- break;
- case t_base_type::TYPE_DOUBLE:
- out << "readDouble:&" << fieldName << " error: __thriftError]";
- break;
- default:
- throw "compiler error: no Objective-C name for base type "
- + t_base_type::t_base_name(tbase);
- }
- } else if (type->is_enum()) {
- out << "readI32:&" << fieldName << " error: __thriftError]";
- }
- out << ") return NO;" << endl;
- } else {
- printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
- tfield->get_name().c_str(),
- type_name(type).c_str());
- }
-}
-
-/**
- * Generates an unserializer for a struct, allocates the struct and invokes read:
- */
-void t_cocoa_generator::generate_deserialize_struct(ostream& out,
- t_struct* tstruct,
- string fieldName) {
- indent(out) << type_name(tstruct) << fieldName << " = [[" << type_name(tstruct, true)
- << " alloc] init];" << endl;
- indent(out) << "if (![" << fieldName << " read: inProtocol error: __thriftError]) return NO;" << endl;
-}
-
-/**
- * Deserializes a container by reading its size and then iterating
- */
-void t_cocoa_generator::generate_deserialize_container(ostream& out,
- t_type* ttype,
- string fieldName) {
- string size = tmp("_size");
- indent(out) << "SInt32 " << size << ";" << endl;
-
- // Declare variables, read header
- if (ttype->is_map()) {
- indent(out) << "if (![inProtocol readMapBeginReturningKeyType: NULL valueType: NULL size: &" << size << " error: __thriftError]) return NO;" << endl;
- indent(out) << "NSMutableDictionary * " << fieldName
- << " = [[NSMutableDictionary alloc] initWithCapacity: " << size << "];" << endl;
- } else if (ttype->is_set()) {
- indent(out) << "if (![inProtocol readSetBeginReturningElementType: NULL size: &" << size << " error: __thriftError]) return NO;"
- << endl;
- indent(out) << "NSMutableSet * " << fieldName
- << " = [[NSMutableSet alloc] initWithCapacity: " << size << "];" << endl;
- } else if (ttype->is_list()) {
- indent(out) << "if (![inProtocol readListBeginReturningElementType: NULL size: &" << size << " error: __thriftError]) return NO;"
- << endl;
- indent(out) << "NSMutableArray * " << fieldName
- << " = [[NSMutableArray alloc] initWithCapacity: " << size << "];" << endl;
- }
- // FIXME - the code above does not verify that the element types of
- // the containers being read match the element types of the
- // containers we are reading into. Does that matter?
-
- // For loop iterates over elements
- string i = tmp("_i");
- indent(out) << "int " << i << ";" << endl << indent() << "for (" << i << " = 0; " << i << " < "
- << size << "; "
- << "++" << i << ")" << endl;
-
- scope_up(out);
-
- if (ttype->is_map()) {
- generate_deserialize_map_element(out, (t_map*)ttype, fieldName);
- } else if (ttype->is_set()) {
- generate_deserialize_set_element(out, (t_set*)ttype, fieldName);
- } else if (ttype->is_list()) {
- generate_deserialize_list_element(out, (t_list*)ttype, fieldName);
- }
-
- scope_down(out);
-
- // Read container end
- if (ttype->is_map()) {
- indent(out) << "if (![inProtocol readMapEnd: __thriftError]) return NO;" << endl;
- } else if (ttype->is_set()) {
- indent(out) << "if (![inProtocol readSetEnd: __thriftError]) return NO;" << endl;
- } else if (ttype->is_list()) {
- indent(out) << "if (![inProtocol readListEnd: __thriftError]) return NO;" << endl;
- }
-}
-
-/**
- * Take a variable of a given type and wrap it in code to make it
- * suitable for putting into a container, if necessary. Basically,
- * wrap scaler primitives in NSNumber objects.
- */
-string t_cocoa_generator::box(t_type* ttype, string field_name) {
-
- ttype = get_true_type(ttype);
- if (ttype->is_enum()) {
- return "@(" + field_name + ")";
- } else if (ttype->is_base_type()) {
- t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_VOID:
- throw "can't box void";
- case t_base_type::TYPE_BOOL:
- case t_base_type::TYPE_I8:
- case t_base_type::TYPE_I16:
- case t_base_type::TYPE_I32:
- case t_base_type::TYPE_I64:
- case t_base_type::TYPE_DOUBLE:
- return "@(" + field_name + ")";
- default:
- break;
- }
- }
-
- // do nothing
- return field_name;
-}
-
-/**
- * Extracts the actual value from a boxed value
- */
-string t_cocoa_generator::unbox(t_type* ttype, string field_name) {
- ttype = get_true_type(ttype);
- if (ttype->is_enum()) {
- return "[" + field_name + " intValue]";
- } else if (ttype->is_base_type()) {
- t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_VOID:
- throw "can't unbox void";
- case t_base_type::TYPE_BOOL:
- return "[" + field_name + " boolValue]";
- case t_base_type::TYPE_I8:
- return "((SInt8)[" + field_name + " charValue])";
- case t_base_type::TYPE_I16:
- return "((SInt16)[" + field_name + " shortValue])";
- case t_base_type::TYPE_I32:
- return "((SInt32)[" + field_name + " longValue])";
- case t_base_type::TYPE_I64:
- return "((SInt64)[" + field_name + " longLongValue])";
- case t_base_type::TYPE_DOUBLE:
- return "[" + field_name + " doubleValue]";
- default:
- break;
- }
- }
-
- // do nothing
- return field_name;
-}
-
-/**
- * Generates code to deserialize a map element
- */
-void t_cocoa_generator::generate_deserialize_map_element(ostream& out,
- t_map* tmap,
- string fieldName) {
- string key = tmp("_key");
- string val = tmp("_val");
- t_type* keyType = tmap->get_key_type();
- t_type* valType = tmap->get_val_type();
- t_field fkey(keyType, key);
- t_field fval(valType, val);
-
- generate_deserialize_field(out, &fkey, key);
- generate_deserialize_field(out, &fval, val);
-
- indent(out) << "[" << fieldName << " setObject: " << box(valType, val)
- << " forKey: " << box(keyType, key) << "];" << endl;
-}
-
-/**
- * Deserializes a set element
- */
-void t_cocoa_generator::generate_deserialize_set_element(ostream& out,
- t_set* tset,
- string fieldName) {
- string elem = tmp("_elem");
- t_type* type = tset->get_elem_type();
- t_field felem(type, elem);
-
- generate_deserialize_field(out, &felem, elem);
-
- indent(out) << "[" << fieldName << " addObject: " << box(type, elem) << "];" << endl;
-}
-
-/**
- * Deserializes a list element
- */
-void t_cocoa_generator::generate_deserialize_list_element(ostream& out,
- t_list* tlist,
- string fieldName) {
- string elem = tmp("_elem");
- t_type* type = tlist->get_elem_type();
- t_field felem(type, elem);
-
- generate_deserialize_field(out, &felem, elem);
-
- indent(out) << "[" << fieldName << " addObject: " << box(type, elem) << "];" << endl;
-}
-
-/**
- * Serializes a field of any type.
- *
- * @param tfield The field to serialize
- * @param fieldName Name to of the variable holding the field
- */
-void t_cocoa_generator::generate_serialize_field(ostream& out, t_field* tfield, string fieldName) {
- t_type* type = get_true_type(tfield->get_type());
-
- // Do nothing for void types
- if (type->is_void()) {
- throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE: " + tfield->get_name();
- }
-
- if (type->is_struct() || type->is_xception()) {
- generate_serialize_struct(out, (t_struct*)type, fieldName);
- } else if (type->is_container()) {
- generate_serialize_container(out, type, fieldName);
- } else if (type->is_base_type() || type->is_enum()) {
- indent(out) << "if (![outProtocol ";
-
- if (type->is_base_type()) {
- t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_VOID:
- throw "compiler error: cannot serialize void field in a struct: " + fieldName;
- break;
- case t_base_type::TYPE_STRING:
- if (type->is_binary()) {
- out << "writeBinary: " << fieldName << " error: __thriftError]";
- } else {
- out << "writeString: " << fieldName << " error: __thriftError]";
- }
- break;
- case t_base_type::TYPE_BOOL:
- out << "writeBool: " << fieldName << " error: __thriftError]";
- break;
- case t_base_type::TYPE_I8:
- out << "writeByte: (UInt8)" << fieldName << " error: __thriftError]";
- break;
- case t_base_type::TYPE_I16:
- out << "writeI16: " << fieldName << " error: __thriftError]";
- break;
- case t_base_type::TYPE_I32:
- out << "writeI32: " << fieldName << " error: __thriftError]";
- break;
- case t_base_type::TYPE_I64:
- out << "writeI64: " << fieldName << " error: __thriftError]";
- break;
- case t_base_type::TYPE_DOUBLE:
- out << "writeDouble: " << fieldName << " error: __thriftError]";
- break;
- default:
- throw "compiler error: no Objective-C name for base type "
- + t_base_type::t_base_name(tbase);
- }
- } else if (type->is_enum()) {
- out << "writeI32: " << fieldName << " error: __thriftError]";
- }
- out << ") return NO;" << endl;
- } else {
- printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s' TYPE '%s'\n",
- tfield->get_name().c_str(),
- type_name(type).c_str());
- }
-}
-
-/**
- * Serialize a struct.
- *
- * @param tstruct The struct to serialize
- * @param fieldName Name of variable holding struct
- */
-void t_cocoa_generator::generate_serialize_struct(ostream& out,
- t_struct* tstruct,
- string fieldName) {
- (void)tstruct;
- out << indent() << "if (![" << fieldName << " write: outProtocol error: __thriftError]) return NO;" << endl;
-}
-
-/**
- * Serializes a container by writing its size then the elements.
- *
- * @param ttype The type of container
- * @param fieldName Name of variable holding container
- */
-void t_cocoa_generator::generate_serialize_container(ostream& out,
- t_type* ttype,
- string fieldName) {
- scope_up(out);
-
- if (ttype->is_map()) {
- indent(out) << "if (![outProtocol writeMapBeginWithKeyType: "
- << type_to_enum(((t_map*)ttype)->get_key_type())
- << " valueType: " << type_to_enum(((t_map*)ttype)->get_val_type()) << " size: (SInt32)["
- << fieldName << " count] error: __thriftError]) return NO;" << endl;
- } else if (ttype->is_set()) {
- indent(out) << "if (![outProtocol writeSetBeginWithElementType: "
- << type_to_enum(((t_set*)ttype)->get_elem_type()) << " size: (SInt32)[" << fieldName
- << " count] error: __thriftError]) return NO;" << endl;
- } else if (ttype->is_list()) {
- indent(out) << "if (![outProtocol writeListBeginWithElementType: "
- << type_to_enum(((t_list*)ttype)->get_elem_type()) << " size: (SInt32)[" << fieldName
- << " count] error: __thriftError]) return NO;" << endl;
- }
-
- string iter = tmp("_iter");
- string key;
- if (ttype->is_map()) {
- key = tmp("key");
- indent(out) << "NSEnumerator * " << iter << " = [" << fieldName << " keyEnumerator];" << endl;
- indent(out) << "id " << key << ";" << endl;
- indent(out) << "while ((" << key << " = [" << iter << " nextObject]))" << endl;
- } else if (ttype->is_set()) {
- key = tmp("obj");
- indent(out) << "NSEnumerator * " << iter << " = [" << fieldName << " objectEnumerator];"
- << endl;
- indent(out) << "id " << key << ";" << endl;
- indent(out) << "while ((" << key << " = [" << iter << " nextObject]))" << endl;
- } else if (ttype->is_list()) {
- key = tmp("idx");
- indent(out) << "int " << key << ";" << endl;
- indent(out) << "for (" << key << " = 0; " << key << " < [" << fieldName << " count]; " << key
- << "++)" << endl;
- }
-
- scope_up(out);
-
- if (ttype->is_map()) {
- generate_serialize_map_element(out, (t_map*)ttype, key, fieldName);
- } else if (ttype->is_set()) {
- generate_serialize_set_element(out, (t_set*)ttype, key);
- } else if (ttype->is_list()) {
- generate_serialize_list_element(out, (t_list*)ttype, key, fieldName);
- }
-
- scope_down(out);
-
- if (ttype->is_map()) {
- indent(out) << "if (![outProtocol writeMapEnd: __thriftError]) return NO;" << endl;
- } else if (ttype->is_set()) {
- indent(out) << "if (![outProtocol writeSetEnd: __thriftError]) return NO;" << endl;
- } else if (ttype->is_list()) {
- indent(out) << "if (![outProtocol writeListEnd: __thriftError]) return NO;" << endl;
- }
-
- scope_down(out);
-}
-
-/**
- * Serializes the members of a map.
- */
-void t_cocoa_generator::generate_serialize_map_element(ostream& out,
- t_map* tmap,
- string key,
- string mapName) {
- t_field kfield(tmap->get_key_type(), key);
- generate_serialize_field(out, &kfield, unbox(kfield.get_type(), key));
- t_field vfield(tmap->get_val_type(), "[" + mapName + " objectForKey: " + key + "]");
- generate_serialize_field(out, &vfield, unbox(vfield.get_type(), vfield.get_name()));
-}
-
-/**
- * Serializes the members of a set.
- */
-void t_cocoa_generator::generate_serialize_set_element(ostream& out,
- t_set* tset,
- string elementName) {
- t_field efield(tset->get_elem_type(), elementName);
- generate_serialize_field(out, &efield, unbox(efield.get_type(), elementName));
-}
-
-/**
- * Serializes the members of a list.
- */
-void t_cocoa_generator::generate_serialize_list_element(ostream& out,
- t_list* tlist,
- string index,
- string listName) {
- t_field efield(tlist->get_elem_type(), "[" + listName + " objectAtIndex: " + index + "]");
- generate_serialize_field(out, &efield, unbox(efield.get_type(), efield.get_name()));
-}
-
-/**
- * Returns an Objective-C name
- *
- * @param ttype The type
- * @param class_ref Do we want a Class reference istead of a type reference?
- * @return Objective-C type name, i.e. NSDictionary<Key,Value> *
- */
-string t_cocoa_generator::type_name(t_type* ttype, bool class_ref, bool needs_mutable) {
- if (ttype->is_typedef()) {
- string name = (needs_mutable && ttype->get_true_type()->is_container()) ? "Mutable" + ttype->get_name() : ttype->get_name();
- t_program* program = ttype->get_program();
- return program ? (program->get_namespace("cocoa") + name) : name;
- }
-
- string result;
- if (ttype->is_base_type()) {
- return base_type_name((t_base_type*)ttype);
- } else if (ttype->is_enum()) {
- return cocoa_prefix_ + ttype->get_name();
- } else if (ttype->is_map()) {
- t_map *map = (t_map *)ttype;
- result = needs_mutable ? "NSMutableDictionary" : "NSDictionary";
- result += "<" + element_type_name(map->get_key_type()) + ", " + element_type_name(map->get_val_type()) + ">";
- } else if (ttype->is_set()) {
- t_set *set = (t_set *)ttype;
- result = needs_mutable ? "NSMutableSet" : "NSSet";
- result += "<" + element_type_name(set->get_elem_type()) + ">";
- } else if (ttype->is_list()) {
- t_list *list = (t_list *)ttype;
- result = needs_mutable ? "NSMutableArray" : "NSArray";
- result += "<" + element_type_name(list->get_elem_type()) + ">";
- } else {
- // Check for prefix
- t_program* program = ttype->get_program();
- if (program != NULL) {
- result = program->get_namespace("cocoa") + ttype->get_name();
- } else {
- result = ttype->get_name();
- }
- }
-
- if (!class_ref) {
- result += " *";
- }
- return result;
-}
-
-/**
- * Returns an Objective-C type name for container types
- *
- * @param ttype the type
- */
-string t_cocoa_generator::element_type_name(t_type* etype) {
-
- t_type* ttype = etype->get_true_type();
-
- if (etype->is_typedef() && type_can_be_null(ttype)) {
- return type_name(etype);
- }
-
- string result;
- if (ttype->is_base_type()) {
- t_base_type* tbase = (t_base_type*)ttype;
- switch (tbase->get_base()) {
- case t_base_type::TYPE_STRING:
- if (tbase->is_binary()) {
- result = "NSData *";
- }
- else {
- result = "NSString *";
- }
- break;
- default:
- result = "NSNumber *";
- break;
- }
- } else if (ttype->is_enum()) {
- result = "NSNumber *";
- } else if (ttype->is_map()) {
- t_map *map = (t_map *)ttype;
- result = "NSDictionary<" + element_type_name(map->get_key_type()) + ", " + element_type_name(map->get_val_type()) + "> *";
- } else if (ttype->is_set()) {
- t_set *set = (t_set *)ttype;
- result = "NSSet<" + element_type_name(set->get_elem_type()) + "> *";
- } else if (ttype->is_list()) {
- t_list *list = (t_list *)ttype;
- result = "NSArray<" + element_type_name(list->get_elem_type()) + "> *";
- } else if (ttype->is_struct() || ttype->is_xception()) {
- result = cocoa_prefix_ + ttype->get_name() + " *";
- }
-
- return result;
-}
-
-/**
- * Returns the Objective-C type that corresponds to the thrift type.
- *
- * @param tbase The base type
- */
-string t_cocoa_generator::base_type_name(t_base_type* type) {
- t_base_type::t_base tbase = type->get_base();
-
- switch (tbase) {
- case t_base_type::TYPE_VOID:
- return "void";
- case t_base_type::TYPE_STRING:
- if (type->is_binary()) {
- return "NSData *";
- } else {
- return "NSString *";
- }
- case t_base_type::TYPE_BOOL:
- return "BOOL";
- case t_base_type::TYPE_I8:
- return "SInt8";
- case t_base_type::TYPE_I16:
- return "SInt16";
- case t_base_type::TYPE_I32:
- return "SInt32";
- case t_base_type::TYPE_I64:
- return "SInt64";
- case t_base_type::TYPE_DOUBLE:
- return "double";
- default:
- throw "compiler error: no Objective-C name for base type " + t_base_type::t_base_name(tbase);
- }
-}
-
-/**
- * Prints the value of a constant with the given type. Note that type checking
- * is NOT performed in this function as it is always run beforehand using the
- * validate_types method in main.cc
- */
-void t_cocoa_generator::print_const_value(ostream& out,
- string name,
- t_type* type,
- t_const_value* value,
- bool defval) {
- type = get_true_type(type);
-
- if (type->is_base_type()) {
- string v2 = render_const_value(out, type, value);
- indent(out);
- if (defval)
- out << type_name(type) << " ";
- out << name << " = " << v2 << ";" << endl << endl;
- } else if (type->is_enum()) {
- indent(out);
- if (defval)
- out << type_name(type) << " ";
- out << name << " = " << render_const_value(out, type, value) << ";" << endl << endl;
- } else if (type->is_struct() || type->is_xception()) {
- indent(out);
- const vector<t_field*>& fields = ((t_struct*)type)->get_members();
- vector<t_field*>::const_iterator f_iter;
- const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
- map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
- if (defval)
- out << type_name(type) << " ";
- out << name << " = [" << type_name(type, true) << " new];"
- << endl;
- for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- t_type* field_type = NULL;
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- if ((*f_iter)->get_name() == v_iter->first->get_string()) {
- field_type = (*f_iter)->get_type();
- }
- }
- if (field_type == NULL) {
- throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
- }
- string val = render_const_value(out, field_type, v_iter->second);
- std::string cap_name = capitalize(v_iter->first->get_string());
- indent(out) << "[" << name << " set" << cap_name << ":" << val << "];" << endl;
- }
- } else if (type->is_map()) {
- ostringstream mapout;
- indent(mapout);
- t_type* ktype = ((t_map*)type)->get_key_type();
- t_type* vtype = ((t_map*)type)->get_val_type();
- const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
- map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
- if (defval)
- mapout << type_name(type) << " ";
- mapout << name << " = @{";
- for (v_iter = val.begin(); v_iter != val.end();) {
- mapout << render_const_value(out, ktype, v_iter->first, true) << ": "
- << render_const_value(out, vtype, v_iter->second, true);
- if (++v_iter != val.end()) {
- mapout << ", ";
- }
- }
- mapout << "}";
- out << mapout.str();
- } else if (type->is_list()) {
- ostringstream listout;
- indent(listout);
- t_type* etype = ((t_list*)type)->get_elem_type();
- const vector<t_const_value*>& val = value->get_list();
- vector<t_const_value*>::const_iterator v_iter;
- if (defval)
- listout << type_name(type) << " ";
- listout << name << " = @[";
- for (v_iter = val.begin(); v_iter != val.end();) {
- listout << render_const_value(out, etype, *v_iter, true);
- if (++v_iter != val.end()) {
- listout << ", ";
- }
- }
- listout << "]";
- out << listout.str();
- } else if (type->is_set()) {
- ostringstream setout;
- indent(setout);
- t_type* etype = ((t_set*)type)->get_elem_type();
- const vector<t_const_value*>& val = value->get_list();
- vector<t_const_value*>::const_iterator v_iter;
- if (defval)
- setout << type_name(type) << " ";
- setout << name << " = [NSSet setWithArray:@[";
- for (v_iter = val.begin(); v_iter != val.end();) {
- setout << render_const_value(out, etype, *v_iter, true);
- if (++v_iter != val.end()) {
- setout << ", ";
- }
- }
- setout << "]]";
- out << setout.str();
- } else {
- throw "compiler error: no const of type " + type->get_name();
- }
-}
-
-string t_cocoa_generator::render_const_value(ostream& out,
- t_type* type,
- t_const_value* value,
- bool box_it) {
- type = get_true_type(type);
- std::ostringstream render;
-
- if (type->is_base_type()) {
- t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_STRING:
- // We must handle binary constant but the syntax of IDL defines
- // nothing about binary constant.
- // if type->is_binary())
- // // binary code
- render << "@\"" << get_escaped_string(value) << '"';
- break;
- case t_base_type::TYPE_BOOL:
- render << ((value->get_integer() > 0) ? "YES" : "NO");
- break;
- case t_base_type::TYPE_I8:
- case t_base_type::TYPE_I16:
- case t_base_type::TYPE_I32:
- case t_base_type::TYPE_I64:
- render << value->get_integer();
- break;
- case t_base_type::TYPE_DOUBLE:
- if (value->get_type() == t_const_value::CV_INTEGER) {
- render << value->get_integer();
- } else {
- render << value->get_double();
- }
- break;
- default:
- throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
- }
- } else if (type->is_enum()) {
- render << value->get_integer();
- } else {
- string t = tmp("tmp");
- print_const_value(out, t, type, value, true);
- out << ";" << endl;
- render << t;
- }
-
- if (box_it) {
- return box(type, render.str());
- }
- return render.str();
-}
-
-#if 0
-/**
-ORIGINAL
- * Spit out code that evaluates to the specified constant value.
- */
-string t_cocoa_generator::render_const_value(string name,
- t_type* type,
- t_const_value* value,
- bool box_it) {
- type = get_true_type(type);
- std::ostringstream render;
-
- if (type->is_base_type()) {
- t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_STRING:
- render << "@\"" << get_escaped_string(value) << '"';
- break;
- case t_base_type::TYPE_BOOL:
- render << ((value->get_integer() > 0) ? "YES" : "NO");
- break;
- case t_base_type::TYPE_I8:
- case t_base_type::TYPE_I16:
- case t_base_type::TYPE_I32:
- case t_base_type::TYPE_I64:
- render << value->get_integer();
- break;
- case t_base_type::TYPE_DOUBLE:
- if (value->get_type() == t_const_value::CV_INTEGER) {
- render << value->get_integer();
- } else {
- render << value->get_double();
- }
- break;
- default:
- throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
- }
- } else if (type->is_enum()) {
- render << value->get_integer();
- } else if (type->is_struct() || type->is_xception()) {
- const vector<t_field*>& fields = ((t_struct*)type)->get_members();
- vector<t_field*>::const_iterator f_iter;
- const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
- map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
- if (val.size() > 0)
- render << "[[" << type_name(type, true) << " alloc] initWith";
- else
- render << "[[" << type_name(type, true) << " alloc] init";
- bool first = true;
- for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- // FIXME The generated code does not match with initWithXXX
- // initializer and causes compile error.
- // Try: test/DebugProtoTest.thrift and test/SmallTest.thrift
- t_type* field_type = NULL;
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- if ((*f_iter)->get_name() == v_iter->first->get_string()) {
- field_type = (*f_iter)->get_type();
- }
- }
- if (field_type == NULL) {
- throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
- }
- if (first) {
- render << capitalize(v_iter->first->get_string());
- first = false;
- } else {
- render << " " << v_iter->first->get_string();
- }
- render << ": " << render_const_value(name, field_type, v_iter->second);
- }
- render << "]";
- } else if (type->is_map()) {
- render << "[[NSDictionary alloc] initWithObjectsAndKeys: ";
- t_type* ktype = ((t_map*)type)->get_key_type();
- t_type* vtype = ((t_map*)type)->get_val_type();
- const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
- map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
- bool first = true;
- for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- string key = render_const_value(name, ktype, v_iter->first, true);
- string val = render_const_value(name, vtype, v_iter->second, true);
- if (first) {
- first = false;
- } else {
- render << ", ";
- }
- render << val << ", " << key;
- }
- if (first)
- render << " nil]";
- else
- render << ", nil]";
- } else if (type->is_list()) {
- render << "[[NSArray alloc] initWithObjects: ";
- t_type * etype = ((t_list*)type)->get_elem_type();
- const vector<t_const_value*>& val = value->get_list();
- bool first = true;
- vector<t_const_value*>::const_iterator v_iter;
- for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- if (first) {
- first = false;
- } else {
- render << ", ";
- }
- render << render_const_value(name, etype, *v_iter, true);
- }
- if (first)
- render << " nil]";
- else
- render << ", nil]";
- } else if (type->is_set()) {
- render << "[[NSSet alloc] initWithObjects: ";
- t_type * etype = ((t_set*)type)->get_elem_type();
- const vector<t_const_value*>& val = value->get_list();
- bool first = true;
- vector<t_const_value*>::const_iterator v_iter;
- for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
- if (first) {
- first = false;
- } else {
- render << ", ";
- }
- render << render_const_value(name, etype, *v_iter, true);
- }
- if (first)
- render << " nil]";
- else
- render << ", nil]";
- } else {
- throw "don't know how to render constant for type: " + type->get_name();
- }
-
- if (box_it) {
- return box(type, render.str());
- }
-
- return render.str();
-}
-#endif
-
-/**
- * Declares an Objective-C 2.0 property.
- *
- * @param tfield The field to declare a property for
- */
-string t_cocoa_generator::declare_property(t_field* tfield) {
- std::ostringstream render;
- render << "@property (";
-
- if (type_can_be_copy(tfield->get_type())) {
- render << "copy, ";
- } else if (type_can_be_null(tfield->get_type())) {
- render << "strong, ";
- } else {
- render << "assign, ";
- }
-
- render << "nonatomic) " << type_name(tfield->get_type(), false, true) << " "
- << tfield->get_name() << ";";
-
- // Check if the property name is an Objective-C return +1 count signal
- if ((tfield->get_name().length() >= 3 && tfield->get_name().substr(0,3) == "new") ||
- (tfield->get_name().length() >= 6 && tfield->get_name().substr(0,6) == "create") ||
- (tfield->get_name().length() >= 5 && tfield->get_name().substr(0,5) == "alloc")) {
- // Let Objective-C know not to return +1 for object pointers
- if (type_can_be_null(tfield->get_type())) {
- render << endl;
- render << "- (" + type_name(tfield->get_type()) + ") " + decapitalize(tfield->get_name()) + " __attribute__((objc_method_family(none)));";
- }
- }
-
- return render.str();
-}
-
-/**
- * Declares an Objective-C 2.0 property.
- *
- * @param tfield The field to declare a property for
- */
-string t_cocoa_generator::declare_property_isset(t_field* tfield) {
- return "@property (assign, nonatomic) BOOL " + decapitalize(tfield->get_name()) + "IsSet;";
-}
-
-/**
- * Declares property unset method.
- *
- * @param tfield The field to declare a property for
- */
-string t_cocoa_generator::declare_property_unset(t_field* tfield) {
- return "- (void) unset" + capitalize(tfield->get_name()) + ";";
-}
-
-/**
- * Renders the early out return statement
- *
- * @param tfunction Function definition
- * @return String of rendered invalid return statment
- */
-string t_cocoa_generator::invalid_return_statement(t_function *tfunction) {
- if ((tfunction->get_returntype()->is_void())) {
- return "return NO;";
- }
- return "return nil;";
-}
-
-/**
- * Renders a function signature
- *
- * @param tfunction Function definition
- * @return String of rendered function definition
- */
-string t_cocoa_generator::function_signature(t_function* tfunction, bool include_error) {
- t_type* ttype = tfunction->get_returntype();
- string result;
- if (ttype->is_void()) {
- result = "(BOOL)";
- }
- else if (type_can_be_null(ttype)) {
- result = "(" + type_name(ttype) + ")";
- }
- else {
- result = "(NSNumber *)";
- }
- result += " " + tfunction->get_name() + argument_list(tfunction->get_arglist(), "", include_error);
- return result;
-}
-
-/**
- * Renders a function signature that returns asynchronously instead of
- * literally returning.
- *
- * @param tfunction Function definition
- * @return String of rendered function definition
- */
-string t_cocoa_generator::async_function_signature(t_function* tfunction, bool include_error) {
- t_type* ttype = tfunction->get_returntype();
- t_struct* targlist = tfunction->get_arglist();
- string response_param = "void (^)(" + ((ttype->is_void()) ? "" : type_name(ttype)) + ")";
- std::string result = "(void) " + tfunction->get_name() + argument_list(tfunction->get_arglist(), "", include_error)
- + (targlist->get_members().size() ? " response" : "") + ": ("
- + response_param + ") responseBlock "
- + "failure : (TAsyncFailureBlock) failureBlock";
- return result;
-}
-
-/**
- * Renders a function signature that returns a promise instead of
- * literally returning.
- *
- * @param tfunction Function definition
- * @return String of rendered function definition
- */
-string t_cocoa_generator::promise_function_signature(t_function* tfunction) {
- return "(AnyPromise *) " + tfunction->get_name() + argument_list(tfunction->get_arglist(), "", false);
-}
-
-/**
- * Renders a colon separated list of types and names, suitable for an
- * objective-c parameter list
- */
-string t_cocoa_generator::argument_list(t_struct* tstruct, string protocol_name, bool include_error) {
- string result = "";
- bool include_protocol = !protocol_name.empty();
-
- const vector<t_field*>& fields = tstruct->get_members();
- vector<t_field*>::const_iterator f_iter;
- bool first = true;
- for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- string argPrefix = "";
- if (first) {
- first = false;
- } else {
- argPrefix = (*f_iter)->get_name();
- result += " ";
- }
- result += argPrefix + ": (" + type_name((*f_iter)->get_type()) + ") " + (*f_iter)->get_name();
- }
- if (include_protocol) {
- if (!first) {
- result += " protocol";
- }
- result += ": (id<TProtocol>) " + protocol_name;
- first = false;
- }
- if (include_error) {
- if (!first) {
- result += " error";
- }
- result += ": (NSError *__autoreleasing *)__thriftError";
- first = false;
- }
- return result;
-}
-
-/**
- * Converts the parse type to an Objective-C enum string for the given type.
- */
-string t_cocoa_generator::type_to_enum(t_type* type) {
- type = get_true_type(type);
-
- if (type->is_base_type()) {
- t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_VOID:
- throw "NO T_VOID CONSTRUCT";
- case t_base_type::TYPE_STRING:
- return "TTypeSTRING";
- case t_base_type::TYPE_BOOL:
- return "TTypeBOOL";
- case t_base_type::TYPE_I8:
- return "TTypeBYTE";
- case t_base_type::TYPE_I16:
- return "TTypeI16";
- case t_base_type::TYPE_I32:
- return "TTypeI32";
- case t_base_type::TYPE_I64:
- return "TTypeI64";
- case t_base_type::TYPE_DOUBLE:
- return "TTypeDOUBLE";
- }
- } else if (type->is_enum()) {
- return "TTypeI32";
- } else if (type->is_struct() || type->is_xception()) {
- return "TTypeSTRUCT";
- } else if (type->is_map()) {
- return "TTypeMAP";
- } else if (type->is_set()) {
- return "TTypeSET";
- } else if (type->is_list()) {
- return "TTypeLIST";
- }
-
- throw "INVALID TYPE IN type_to_enum: " + type->get_name();
-}
-
-/**
- * Returns a format string specifier for the supplied parse type.
- */
-string t_cocoa_generator::format_string_for_type(t_type* type) {
- type = get_true_type(type);
-
- if (type->is_base_type()) {
- t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_VOID:
- throw "NO T_VOID CONSTRUCT";
- case t_base_type::TYPE_STRING:
- return "\\\"%@\\\"";
- case t_base_type::TYPE_BOOL:
- return "%i";
- case t_base_type::TYPE_I8:
- return "%i";
- case t_base_type::TYPE_I16:
- return "%hi";
- case t_base_type::TYPE_I32:
- return "%i";
- case t_base_type::TYPE_I64:
- return "%qi";
- case t_base_type::TYPE_DOUBLE:
- return "%f";
- }
- } else if (type->is_enum()) {
- return "%i";
- } else if (type->is_struct() || type->is_xception()) {
- return "%@";
- } else if (type->is_map()) {
- return "%@";
- } else if (type->is_set()) {
- return "%@";
- } else if (type->is_list()) {
- return "%@";
- }
-
- throw "INVALID TYPE IN format_string_for_type: " + type->get_name();
-}
-
-/**
- * Returns a format cast for the supplied parse type.
- */
-string t_cocoa_generator::format_cast_for_type(t_type* type) {
- type = get_true_type(type);
-
- if (type->is_base_type()) {
- t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
- switch (tbase) {
- case t_base_type::TYPE_VOID:
- throw "NO T_VOID CONSTRUCT";
- case t_base_type::TYPE_STRING:
- return ""; // "\\\"%@\\\"";
- case t_base_type::TYPE_BOOL:
- return ""; // "%i";
- case t_base_type::TYPE_I8:
- return ""; // "%i";
- case t_base_type::TYPE_I16:
- return ""; // "%hi";
- case t_base_type::TYPE_I32:
- return "(int)"; // "%i";
- case t_base_type::TYPE_I64:
- return ""; // "%qi";
- case t_base_type::TYPE_DOUBLE:
- return ""; // "%f";
- }
- } else if (type->is_enum()) {
- return "(int)"; // "%i";
- } else if (type->is_struct() || type->is_xception()) {
- return ""; // "%@";
- } else if (type->is_map()) {
- return ""; // "%@";
- } else if (type->is_set()) {
- return ""; // "%@";
- } else if (type->is_list()) {
- return ""; // "%@";
- }
-
- throw "INVALID TYPE IN format_cast_for_type: " + type->get_name();
-}
-
-/**
- * Generate a call to a field's setter.
- *
- * @param tfield Field the setter is being called on
- * @param fieldName Name of variable to pass to setter
- */
-
-string t_cocoa_generator::call_field_setter(t_field* tfield, string fieldName) {
- return "self." + tfield->get_name() + " = " + fieldName + ";";
-}
-
-THRIFT_REGISTER_GENERATOR(
- cocoa,
- "Cocoa",
- " log_unexpected: Log every time an unexpected field ID or type is encountered.\n"
- " debug_descriptions:\n"
- " Allow use of debugDescription so the app can add description via a cateogory/extension\n"
- " validate_required:\n"
- " Throws exception if any required field is not set.\n"
- " async_clients: Generate clients which invoke asynchronously via block syntax.\n"
- " pods: Generate imports in Cocopods framework format.\n"
- " promise_kit: Generate clients which invoke asynchronously via promises.\n")
diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
index 3e8f728..dca3167 100644
--- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
@@ -101,25 +101,25 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
- void generate_consts(std::vector<t_const*> consts);
+ void generate_consts(std::vector<t_const*> consts) override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
void generate_enum_ostream_operator_decl(std::ostream& out, t_enum* tenum);
void generate_enum_ostream_operator(std::ostream& out, t_enum* tenum);
- void generate_forward_declaration(t_struct* tstruct);
- void generate_struct(t_struct* tstruct) { generate_cpp_struct(tstruct, false); }
- void generate_xception(t_struct* txception) { generate_cpp_struct(txception, true); }
+ void generate_forward_declaration(t_struct* tstruct) override;
+ void generate_struct(t_struct* tstruct) override { generate_cpp_struct(tstruct, false); }
+ void generate_xception(t_struct* txception) override { generate_cpp_struct(txception, true); }
void generate_cpp_struct(t_struct* tstruct, bool is_exception);
- void generate_service(t_service* tservice);
+ void generate_service(t_service* tservice) override;
void print_const_value(std::ostream& out, std::string name, t_type* type, t_const_value* value);
std::string render_const_value(std::ostream& out,
@@ -419,28 +419,29 @@
<< "#include <thrift/transport/TTransport.h>" << endl
<< endl;
// Include C++xx compatibility header
- f_types_ << "#include <thrift/stdcxx.h>" << endl;
+ f_types_ << "#include <functional>" << endl;
+ f_types_ << "#include <memory>" << endl;
// Include other Thrift includes
const vector<t_program*>& includes = program_->get_includes();
- for (size_t i = 0; i < includes.size(); ++i) {
- f_types_ << "#include \"" << get_include_prefix(*(includes[i])) << includes[i]->get_name()
+ for (auto include : includes) {
+ f_types_ << "#include \"" << get_include_prefix(*include) << include->get_name()
<< "_types.h\"" << endl;
// XXX(simpkins): If gen_templates_ is enabled, we currently assume all
// included files were also generated with templates enabled.
- f_types_tcc_ << "#include \"" << get_include_prefix(*(includes[i])) << includes[i]->get_name()
+ f_types_tcc_ << "#include \"" << get_include_prefix(*include) << include->get_name()
<< "_types.tcc\"" << endl;
}
f_types_ << endl;
// Include custom headers
const vector<string>& cpp_includes = program_->get_cpp_includes();
- for (size_t i = 0; i < cpp_includes.size(); ++i) {
- if (cpp_includes[i][0] == '<') {
- f_types_ << "#include " << cpp_includes[i] << endl;
+ for (const auto & cpp_include : cpp_includes) {
+ if (cpp_include[0] == '<') {
+ f_types_ << "#include " << cpp_include << endl;
} else {
- f_types_ << "#include \"" << cpp_includes[i] << "\"" << endl;
+ f_types_ << "#include \"" << cpp_include << "\"" << endl;
}
}
f_types_ << endl;
@@ -1097,7 +1098,7 @@
}
if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
- out << endl << indent() << "virtual ~" << tstruct->get_name() << "() throw();" << endl;
+ out << endl << indent() << "virtual ~" << tstruct->get_name() << "() noexcept;" << endl;
}
// Declare all fields
@@ -1119,7 +1120,7 @@
continue;
}
if (is_reference((*m_iter))) {
- out << endl << indent() << "void __set_" << (*m_iter)->get_name() << "(::apache::thrift::stdcxx::shared_ptr<"
+ out << endl << indent() << "void __set_" << (*m_iter)->get_name() << "(::std::shared_ptr<"
<< type_name((*m_iter)->get_type(), false, false) << ">";
out << " val);" << endl;
} else {
@@ -1226,7 +1227,7 @@
// Destructor
if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
force_cpp_out << endl << indent() << tstruct->get_name() << "::~" << tstruct->get_name()
- << "() throw() {" << endl;
+ << "() noexcept {" << endl;
indent_up();
indent_down();
@@ -1237,9 +1238,8 @@
if (setters) {
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
if (is_reference((*m_iter))) {
- std::string type = type_name((*m_iter)->get_type());
out << endl << indent() << "void " << tstruct->get_name() << "::__set_"
- << (*m_iter)->get_name() << "(::apache::thrift::stdcxx::shared_ptr<"
+ << (*m_iter)->get_name() << "(::std::shared_ptr<"
<< type_name((*m_iter)->get_type(), false, false) << ">";
out << " val) {" << endl;
} else {
@@ -1537,9 +1537,7 @@
bool has_nonrequired_fields = false;
const vector<t_field*>& fields = tstruct->get_members();
- for (vector<t_field*>::const_iterator f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- t_field* tfield = *f_iter;
-
+ for (auto tfield : fields) {
if (tfield->get_req() != t_field::T_REQUIRED) {
has_nonrequired_fields = true;
}
@@ -1598,7 +1596,7 @@
if (external) {
out << tstruct->get_name() << "::";
}
- out << "what() const throw()";
+ out << "what() const noexcept";
}
namespace struct_ostream_operator_generator {
@@ -1717,8 +1715,8 @@
f_header_ << "#ifndef " << svcname << "_H" << endl << "#define " << svcname << "_H" << endl
<< endl;
if (gen_cob_style_) {
- f_header_ << "#include <thrift/transport/TBufferTransports.h>" << endl << // TMemoryBuffer
- "#include <thrift/stdcxx.h>" << endl
+ f_header_ << "#include <thrift/transport/TBufferTransports.h>" << endl // TMemoryBuffer
+ << "#include <functional>" << endl
<< "namespace apache { namespace thrift { namespace async {" << endl
<< "class TAsyncChannel;" << endl << "}}}" << endl;
}
@@ -1727,6 +1725,7 @@
f_header_ << "#include <thrift/async/TAsyncDispatchProcessor.h>" << endl;
}
f_header_ << "#include <thrift/async/TConcurrentClientSyncInfo.h>" << endl;
+ f_header_ << "#include <memory>" << endl;
f_header_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ << "_types.h\""
<< endl;
@@ -1968,7 +1967,7 @@
f_header_ << "class " << singleton_factory_name << " : virtual public " << factory_name << " {"
<< endl << " public:" << endl;
indent_up();
- f_header_ << indent() << singleton_factory_name << "(const ::apache::thrift::stdcxx::shared_ptr<" << service_if_name
+ f_header_ << indent() << singleton_factory_name << "(const ::std::shared_ptr<" << service_if_name
<< ">& iface) : iface_(iface) {}" << endl << indent() << "virtual ~"
<< singleton_factory_name << "() {}" << endl << endl << indent() << "virtual "
<< service_if_name << "* getHandler("
@@ -1976,7 +1975,7 @@
<< " return iface_.get();" << endl << indent() << "}" << endl << indent()
<< "virtual void releaseHandler(" << base_if_name << "* /* handler */) {}" << endl;
- f_header_ << endl << " protected:" << endl << indent() << "::apache::thrift::stdcxx::shared_ptr<" << service_if_name
+ f_header_ << endl << " protected:" << endl << indent() << "::std::shared_ptr<" << service_if_name
<< "> iface_;" << endl;
indent_down();
@@ -2146,7 +2145,7 @@
extends_multiface = ", public " + extends + "Multiface";
}
- string list_type = string("std::vector<apache::thrift::stdcxx::shared_ptr<") + service_name_ + "If> >";
+ string list_type = string("std::vector<std::shared_ptr<") + service_name_ + "If> >";
// Generate the header portion
f_header_ << "class " << service_name_ << "Multiface : "
@@ -2157,7 +2156,7 @@
<< "& ifaces) : ifaces_(ifaces) {" << endl;
if (!extends.empty()) {
f_header_ << indent()
- << " std::vector<apache::thrift::stdcxx::shared_ptr<" + service_name_ + "If> >::iterator iter;"
+ << " std::vector<std::shared_ptr<" + service_name_ + "If> >::iterator iter;"
<< endl << indent() << " for (iter = ifaces.begin(); iter != ifaces.end(); ++iter) {"
<< endl << indent() << " " << extends << "Multiface::add(*iter);" << endl
<< indent() << " }" << endl;
@@ -2170,7 +2169,7 @@
f_header_ << " protected:" << endl;
indent_up();
f_header_ << indent() << list_type << " ifaces_;" << endl << indent() << service_name_
- << "Multiface() {}" << endl << indent() << "void add(::apache::thrift::stdcxx::shared_ptr<"
+ << "Multiface() {}" << endl << indent() << "void add(::std::shared_ptr<"
<< service_name_ << "If> iface) {" << endl;
if (!extends.empty()) {
f_header_ << indent() << " " << extends << "Multiface::add(iface);" << endl;
@@ -2252,7 +2251,7 @@
} else {
protocol_type = "::apache::thrift::protocol::TProtocol";
}
- string prot_ptr = "apache::thrift::stdcxx::shared_ptr< " + protocol_type + ">";
+ string prot_ptr = "std::shared_ptr< " + protocol_type + ">";
string client_suffix = "Client" + template_suffix;
string if_suffix = "If";
if (style == "Cob") {
@@ -2282,27 +2281,49 @@
indent_up();
if (style != "Cob") {
f_header_ << indent() << service_name_ << style << "Client" << short_suffix << "(" << prot_ptr
- << " prot) ";
+ << " prot";
+ if (style == "Concurrent") {
+ f_header_ << ", std::shared_ptr<::apache::thrift::async::TConcurrentClientSyncInfo> sync";
+ }
+ f_header_ << ") ";
if (extends.empty()) {
+ if (style == "Concurrent") {
+ f_header_ << ": sync_(sync)" << endl;
+ }
f_header_ << "{" << endl;
f_header_ << indent() << " setProtocol" << short_suffix << "(prot);" << endl << indent()
<< "}" << endl;
} else {
f_header_ << ":" << endl;
- f_header_ << indent() << " " << extends << style << client_suffix << "(prot, prot) {}"
- << endl;
+ f_header_ << indent() << " " << extends << style << client_suffix << "(prot, prot";
+ if (style == "Concurrent") {
+ f_header_ << ", sync";
+ }
+ f_header_ << ") {}" << endl;
}
f_header_ << indent() << service_name_ << style << "Client" << short_suffix << "(" << prot_ptr
- << " iprot, " << prot_ptr << " oprot) ";
+ << " iprot, " << prot_ptr << " oprot";
+ if (style == "Concurrent") {
+ f_header_ << ", std::shared_ptr<::apache::thrift::async::TConcurrentClientSyncInfo> sync";
+ }
+ f_header_ << ") ";
+
if (extends.empty()) {
+ if (style == "Concurrent") {
+ f_header_ << ": sync_(sync)" << endl;
+ }
f_header_ << "{" << endl;
f_header_ << indent() << " setProtocol" << short_suffix << "(iprot,oprot);" << endl
<< indent() << "}" << endl;
} else {
f_header_ << ":" << indent() << " " << extends << style << client_suffix
- << "(iprot, oprot) {}" << endl;
+ << "(iprot, oprot";
+ if (style == "Concurrent") {
+ f_header_ << ", sync";
+ }
+ f_header_ << ") {}" << endl;
}
// create the setProtocol methods
@@ -2329,18 +2350,18 @@
// Note that these are not currently templated for simplicity.
// TODO(simpkins): should they be templated?
f_header_ << indent()
- << "apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {"
+ << "std::shared_ptr< ::apache::thrift::protocol::TProtocol> getInputProtocol() {"
<< endl << indent() << " return " << _this << "piprot_;" << endl << indent() << "}"
<< endl;
f_header_ << indent()
- << "apache::thrift::stdcxx::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {"
+ << "std::shared_ptr< ::apache::thrift::protocol::TProtocol> getOutputProtocol() {"
<< endl << indent() << " return " << _this << "poprot_;" << endl << indent() << "}"
<< endl;
} else /* if (style == "Cob") */ {
f_header_ << indent() << service_name_ << style << "Client" << short_suffix << "("
- << "apache::thrift::stdcxx::shared_ptr< ::apache::thrift::async::TAsyncChannel> channel, "
+ << "std::shared_ptr< ::apache::thrift::async::TAsyncChannel> channel, "
<< "::apache::thrift::protocol::TProtocolFactory* protocolFactory) :" << endl;
if (extends.empty()) {
f_header_ << indent() << " channel_(channel)," << endl << indent()
@@ -2350,9 +2371,9 @@
if (gen_templates_) {
// TProtocolFactory classes return generic TProtocol pointers.
// We have to dynamic cast to the Protocol_ type we are expecting.
- f_header_ << indent() << " piprot_(::apache::thrift::stdcxx::dynamic_pointer_cast<Protocol_>("
+ f_header_ << indent() << " piprot_(::std::dynamic_pointer_cast<Protocol_>("
<< "protocolFactory->getProtocol(itrans_)))," << endl << indent()
- << " poprot_(::apache::thrift::stdcxx::dynamic_pointer_cast<Protocol_>("
+ << " poprot_(::std::dynamic_pointer_cast<Protocol_>("
<< "protocolFactory->getProtocol(otrans_))) {" << endl;
// Throw a TException if either dynamic cast failed.
f_header_ << indent() << " if (!piprot_ || !poprot_) {" << endl << indent()
@@ -2374,7 +2395,7 @@
if (style == "Cob") {
f_header_ << indent()
- << "::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::async::TAsyncChannel> getChannel() {" << endl
+ << "::std::shared_ptr< ::apache::thrift::async::TAsyncChannel> getChannel() {" << endl
<< indent() << " return " << _this << "channel_;" << endl << indent() << "}" << endl;
if (!gen_no_client_completion_) {
f_header_ << indent() << "virtual void completed__(bool /* success */) {}" << endl;
@@ -2426,11 +2447,11 @@
if (style == "Cob") {
f_header_ << indent()
- << "::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::async::TAsyncChannel> channel_;" << endl
+ << "::std::shared_ptr< ::apache::thrift::async::TAsyncChannel> channel_;" << endl
<< indent()
- << "::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::transport::TMemoryBuffer> itrans_;" << endl
+ << "::std::shared_ptr< ::apache::thrift::transport::TMemoryBuffer> itrans_;" << endl
<< indent()
- << "::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::transport::TMemoryBuffer> otrans_;"
+ << "::std::shared_ptr< ::apache::thrift::transport::TMemoryBuffer> otrans_;"
<< endl;
}
f_header_ <<
@@ -2441,7 +2462,7 @@
if (style == "Concurrent") {
f_header_ <<
- indent() << "::apache::thrift::async::TConcurrentClientSyncInfo sync_;"<<endl;
+ indent() << "std::shared_ptr<::apache::thrift::async::TConcurrentClientSyncInfo> sync_;"<<endl;
}
indent_down();
}
@@ -2512,11 +2533,11 @@
} else {
if (!(*f_iter)->is_oneway()) {
out << indent() << _this << "channel_->sendAndRecvMessage("
- << "::apache::thrift::stdcxx::bind(cob, this), " << _this << "otrans_.get(), " << _this << "itrans_.get());"
+ << "::std::bind(cob, this), " << _this << "otrans_.get(), " << _this << "itrans_.get());"
<< endl;
} else {
out << indent() << _this << "channel_->sendMessage("
- << "::apache::thrift::stdcxx::bind(cob, this), " << _this << "otrans_.get());" << endl;
+ << "::std::bind(cob, this), " << _this << "otrans_.get());" << endl;
}
}
scope_down(out);
@@ -2547,7 +2568,7 @@
string cseqidVal = "0";
if (style == "Concurrent") {
if (!(*f_iter)->is_oneway()) {
- cseqidVal = "this->sync_.generateSeqId()";
+ cseqidVal = "this->sync_->generateSeqId()";
}
}
// Serialize the request
@@ -2555,7 +2576,7 @@
indent() << "int32_t cseqid = " << cseqidVal << ";" << endl;
if(style == "Concurrent") {
out <<
- indent() << "::apache::thrift::async::TConcurrentSendSentry sentry(&this->sync_);" << endl;
+ indent() << "::apache::thrift::async::TConcurrentSendSentry sentry(this->sync_.get());" << endl;
}
if (style == "Cob") {
out <<
@@ -2620,7 +2641,7 @@
endl <<
indent() << "// the read mutex gets dropped and reacquired as part of waitForWork()" << endl <<
indent() << "// The destructor of this sentry wakes up other clients" << endl <<
- indent() << "::apache::thrift::async::TConcurrentRecvSentry sentry(&this->sync_, seqid);" << endl;
+ indent() << "::apache::thrift::async::TConcurrentRecvSentry sentry(this->sync_.get(), seqid);" << endl;
}
if (style == "Cob" && !gen_no_client_completion_) {
out << indent() << "bool completed = false;" << endl << endl << indent() << "try {";
@@ -2630,7 +2651,7 @@
if (style == "Concurrent") {
out <<
indent() << "while(true) {" << endl <<
- indent() << " if(!this->sync_.getPending(fname, mtype, rseqid)) {" << endl;
+ indent() << " if(!this->sync_->getPending(fname, mtype, rseqid)) {" << endl;
indent_up();
indent_up();
}
@@ -2774,10 +2795,10 @@
out <<
indent() << " }" << endl <<
indent() << " // seqid != rseqid" << endl <<
- indent() << " this->sync_.updatePending(fname, mtype, rseqid);" << endl <<
+ indent() << " this->sync_->updatePending(fname, mtype, rseqid);" << endl <<
endl <<
indent() << " // this will temporarily unlock the readMutex, and let other clients get work done" << endl <<
- indent() << " this->sync_.waitForWork(seqid);" << endl <<
+ indent() << " this->sync_->waitForWork(seqid);" << endl <<
indent() << "} // end while(true)" << endl;
}
if (style == "Cob" && !gen_no_client_completion_) {
@@ -2867,8 +2888,8 @@
class_name_ = service_name_ + pstyle_ + "Processor";
if_name_ = service_name_ + "CobSvIf";
- finish_cob_ = "::apache::thrift::stdcxx::function<void(bool ok)> cob, ";
- finish_cob_decl_ = "::apache::thrift::stdcxx::function<void(bool ok)>, ";
+ finish_cob_ = "::std::function<void(bool ok)> cob, ";
+ finish_cob_decl_ = "::std::function<void(bool ok)>, ";
cob_arg_ = "cob, ";
ret_type_ = "void ";
} else {
@@ -2929,7 +2950,7 @@
// Protected data members
f_header_ << " protected:" << endl;
indent_up();
- f_header_ << indent() << "::apache::thrift::stdcxx::shared_ptr<" << if_name_ << "> iface_;" << endl;
+ f_header_ << indent() << "::std::shared_ptr<" << if_name_ << "> iface_;" << endl;
f_header_ << indent() << "virtual " << ret_type_ << "dispatchCall(" << finish_cob_
<< "::apache::thrift::protocol::TProtocol* iprot, "
<< "::apache::thrift::protocol::TProtocol* oprot, "
@@ -2985,29 +3006,29 @@
? ""
: ", const " + type_name((*f_iter)->get_returntype()) + "& _return");
f_header_ << indent() << "void return_" << (*f_iter)->get_name()
- << "(::apache::thrift::stdcxx::function<void(bool ok)> cob, int32_t seqid, "
+ << "(::std::function<void(bool ok)> cob, int32_t seqid, "
<< "::apache::thrift::protocol::TProtocol* oprot, "
<< "void* ctx" << ret_arg << ");" << endl;
if (generator_->gen_templates_) {
f_header_ << indent() << "void return_" << (*f_iter)->get_name()
- << "(::apache::thrift::stdcxx::function<void(bool ok)> cob, int32_t seqid, "
+ << "(::std::function<void(bool ok)> cob, int32_t seqid, "
<< "Protocol_* oprot, void* ctx" << ret_arg << ");" << endl;
}
// XXX Don't declare throw if it doesn't exist
f_header_ << indent() << "void throw_" << (*f_iter)->get_name()
- << "(::apache::thrift::stdcxx::function<void(bool ok)> cob, int32_t seqid, "
+ << "(::std::function<void(bool ok)> cob, int32_t seqid, "
<< "::apache::thrift::protocol::TProtocol* oprot, void* ctx, "
<< "::apache::thrift::TDelayedException* _throw);" << endl;
if (generator_->gen_templates_) {
f_header_ << indent() << "void throw_" << (*f_iter)->get_name()
- << "(::apache::thrift::stdcxx::function<void(bool ok)> cob, int32_t seqid, "
+ << "(::std::function<void(bool ok)> cob, int32_t seqid, "
<< "Protocol_* oprot, void* ctx, "
<< "::apache::thrift::TDelayedException* _throw);" << endl;
}
}
}
- f_header_ << " public:" << endl << indent() << class_name_ << "(::apache::thrift::stdcxx::shared_ptr<" << if_name_
+ f_header_ << " public:" << endl << indent() << class_name_ << "(::std::shared_ptr<" << if_name_
<< "> iface) :" << endl;
if (!extends_.empty()) {
f_header_ << indent() << " " << extends_ << "(iface)," << endl;
@@ -3145,14 +3166,14 @@
<< endl << " public:" << endl;
indent_up();
- f_header_ << indent() << factory_class_name_ << "(const ::apache::thrift::stdcxx::shared_ptr< " << if_factory_name
+ f_header_ << indent() << factory_class_name_ << "(const ::std::shared_ptr< " << if_factory_name
<< " >& handlerFactory) :" << endl << indent()
<< " handlerFactory_(handlerFactory) {}" << endl << endl << indent()
- << "::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::"
+ << "::std::shared_ptr< ::apache::thrift::"
<< (style_ == "Cob" ? "async::TAsyncProcessor" : "TProcessor") << " > "
<< "getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);" << endl;
- f_header_ << endl << " protected:" << endl << indent() << "::apache::thrift::stdcxx::shared_ptr< "
+ f_header_ << endl << " protected:" << endl << indent() << "::std::shared_ptr< "
<< if_factory_name << " > handlerFactory_;" << endl;
indent_down();
@@ -3167,17 +3188,17 @@
}
// Generate the getProcessor() method
- f_out_ << template_header_ << indent() << "::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::"
+ f_out_ << template_header_ << indent() << "::std::shared_ptr< ::apache::thrift::"
<< (style_ == "Cob" ? "async::TAsyncProcessor" : "TProcessor") << " > "
<< factory_class_name_ << template_suffix_ << "::getProcessor("
<< "const ::apache::thrift::TConnectionInfo& connInfo) {" << endl;
indent_up();
f_out_ << indent() << "::apache::thrift::ReleaseHandler< " << if_factory_name
- << " > cleanup(handlerFactory_);" << endl << indent() << "::apache::thrift::stdcxx::shared_ptr< "
+ << " > cleanup(handlerFactory_);" << endl << indent() << "::std::shared_ptr< "
<< if_name_ << " > handler("
<< "handlerFactory_->getHandler(connInfo), cleanup);" << endl << indent()
- << "::apache::thrift::stdcxx::shared_ptr< ::apache::thrift::"
+ << "::std::shared_ptr< ::apache::thrift::"
<< (style_ == "Cob" ? "async::TAsyncProcessor" : "TProcessor") << " > "
<< "processor(new " << class_name_ << template_suffix_ << "(handler));" << endl << indent()
<< "return processor;" << endl;
@@ -3412,7 +3433,7 @@
out << indent() << "template <class Protocol_>" << endl;
}
out << "void " << tservice->get_name() << "AsyncProcessor" << class_suffix << "::process_"
- << tfunction->get_name() << "(::apache::thrift::stdcxx::function<void(bool ok)> cob, int32_t seqid, "
+ << tfunction->get_name() << "(::std::function<void(bool ok)> cob, int32_t seqid, "
<< prot_type << "* iprot, " << prot_type << "* oprot)" << endl;
scope_up(out);
@@ -3469,28 +3490,28 @@
// No return. Just hand off our cob.
// TODO(dreiss): Call the cob immediately?
out << indent() << "iface_->" << tfunction->get_name() << "("
- << "::apache::thrift::stdcxx::bind(cob, true)" << endl;
+ << "::std::bind(cob, true)" << endl;
indent_up();
indent_up();
} else {
string ret_arg, ret_placeholder;
if (!tfunction->get_returntype()->is_void()) {
ret_arg = ", const " + type_name(tfunction->get_returntype()) + "& _return";
- ret_placeholder = ", ::apache::thrift::stdcxx::placeholders::_1";
+ ret_placeholder = ", ::std::placeholders::_1";
}
// When gen_templates_ is true, the return_ and throw_ functions are
// overloaded. We have to declare pointers to them so that the compiler
// can resolve the correct overloaded version.
out << indent() << "void (" << tservice->get_name() << "AsyncProcessor" << class_suffix
- << "::*return_fn)(::apache::thrift::stdcxx::function<void(bool ok)> "
+ << "::*return_fn)(::std::function<void(bool ok)> "
<< "cob, int32_t seqid, " << prot_type << "* oprot, void* ctx" << ret_arg
<< ") =" << endl;
out << indent() << " &" << tservice->get_name() << "AsyncProcessor" << class_suffix
<< "::return_" << tfunction->get_name() << ";" << endl;
if (!xceptions.empty()) {
out << indent() << "void (" << tservice->get_name() << "AsyncProcessor" << class_suffix
- << "::*throw_fn)(::apache::thrift::stdcxx::function<void(bool ok)> "
+ << "::*throw_fn)(::std::function<void(bool ok)> "
<< "cob, int32_t seqid, " << prot_type << "* oprot, void* ctx, "
<< "::apache::thrift::TDelayedException* _throw) =" << endl;
out << indent() << " &" << tservice->get_name() << "AsyncProcessor" << class_suffix
@@ -3500,11 +3521,11 @@
out << indent() << "iface_->" << tfunction->get_name() << "(" << endl;
indent_up();
indent_up();
- out << indent() << "::apache::thrift::stdcxx::bind(return_fn, this, cob, seqid, oprot, ctx" << ret_placeholder
+ out << indent() << "::std::bind(return_fn, this, cob, seqid, oprot, ctx" << ret_placeholder
<< ")";
if (!xceptions.empty()) {
- out << ',' << endl << indent() << "::apache::thrift::stdcxx::bind(throw_fn, this, cob, seqid, oprot, "
- << "ctx, ::apache::thrift::stdcxx::placeholders::_1)";
+ out << ',' << endl << indent() << "::std::bind(throw_fn, this, cob, seqid, oprot, "
+ << "ctx, ::std::placeholders::_1)";
}
}
@@ -3529,7 +3550,7 @@
out << indent() << "template <class Protocol_>" << endl;
}
out << "void " << tservice->get_name() << "AsyncProcessor" << class_suffix << "::return_"
- << tfunction->get_name() << "(::apache::thrift::stdcxx::function<void(bool ok)> cob, int32_t seqid, "
+ << tfunction->get_name() << "(::std::function<void(bool ok)> cob, int32_t seqid, "
<< prot_type << "* oprot, void* ctx" << ret_arg_decl << ')' << endl;
scope_up(out);
@@ -3577,7 +3598,7 @@
out << indent() << "template <class Protocol_>" << endl;
}
out << "void " << tservice->get_name() << "AsyncProcessor" << class_suffix << "::throw_"
- << tfunction->get_name() << "(::apache::thrift::stdcxx::function<void(bool ok)> cob, int32_t seqid, "
+ << tfunction->get_name() << "(::std::function<void(bool ok)> cob, int32_t seqid, "
<< prot_type << "* oprot, void* ctx, "
<< "::apache::thrift::TDelayedException* _throw)" << endl;
scope_up(out);
@@ -3707,13 +3728,13 @@
f_skeleton << indent() << "int main(int argc, char **argv) {" << endl;
indent_up();
f_skeleton
- << indent() << "int port = 9090;" << endl << indent() << "::apache::thrift::stdcxx::shared_ptr<" << svcname
+ << indent() << "int port = 9090;" << endl << indent() << "::std::shared_ptr<" << svcname
<< "Handler> handler(new " << svcname << "Handler());" << endl << indent()
- << "::apache::thrift::stdcxx::shared_ptr<TProcessor> processor(new " << svcname << "Processor(handler));" << endl
- << indent() << "::apache::thrift::stdcxx::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));"
+ << "::std::shared_ptr<TProcessor> processor(new " << svcname << "Processor(handler));" << endl
+ << indent() << "::std::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));"
<< endl << indent()
- << "::apache::thrift::stdcxx::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());" << endl
- << indent() << "::apache::thrift::stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());"
+ << "::std::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());" << endl
+ << indent() << "::std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());"
<< endl << endl << indent()
<< "TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);"
<< endl << indent() << "server.serve();" << endl << indent() << "return 0;" << endl;
@@ -3802,7 +3823,7 @@
bool pointer) {
if (pointer) {
indent(out) << "if (!" << prefix << ") { " << endl;
- indent(out) << " " << prefix << " = ::apache::thrift::stdcxx::shared_ptr<" << type_name(tstruct) << ">(new "
+ indent(out) << " " << prefix << " = ::std::shared_ptr<" << type_name(tstruct) << ">(new "
<< type_name(tstruct) << ");" << endl;
indent(out) << "}" << endl;
indent(out) << "xfer += " << prefix << "->read(iprot);" << endl;
@@ -4294,7 +4315,7 @@
}
result += type_name(tfield->get_type());
if (is_reference(tfield)) {
- result = "::apache::thrift::stdcxx::shared_ptr<" + result + ">";
+ result = "::std::shared_ptr<" + result + ">";
}
if (pointer) {
result += "*";
@@ -4373,13 +4394,13 @@
cob_type = (ttype->is_void() ? "()" : ("(" + type_name(ttype) + " const& _return)"));
if (has_xceptions) {
exn_cob
- = ", ::apache::thrift::stdcxx::function<void(::apache::thrift::TDelayedException* _throw)> /* exn_cob */";
+ = ", ::std::function<void(::apache::thrift::TDelayedException* _throw)> /* exn_cob */";
}
} else {
throw "UNKNOWN STYLE";
}
- return "void " + prefix + tfunction->get_name() + "(::apache::thrift::stdcxx::function<void" + cob_type + "> cob"
+ return "void " + prefix + tfunction->get_name() + "(::std::function<void" + cob_type + "> cob"
+ exn_cob + argument_list(arglist, name_params, true) + ")";
} else {
throw "UNKNOWN STYLE";
diff --git a/compiler/cpp/src/thrift/generate/t_csharp_generator.cc b/compiler/cpp/src/thrift/generate/t_csharp_generator.cc
index 37d6f9d..e4d99b2 100644
--- a/compiler/cpp/src/thrift/generate/t_csharp_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_csharp_generator.cc
@@ -89,17 +89,17 @@
out_dir_base_ = "gen-csharp";
}
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
- void generate_consts(std::vector<t_const*> consts);
+ void generate_consts(std::vector<t_const*> consts) override;
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_struct(t_struct* tstruct);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_struct(t_struct* tstruct) override;
void generate_union(t_struct* tunion);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
void generate_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset);
void generate_csharp_property(ostream& out,
t_field* tfield,
@@ -207,7 +207,7 @@
std::string argument_list(t_struct* tstruct);
std::string type_to_enum(t_type* ttype);
std::string prop_name(t_field* tfield, bool suppress_mapping = false);
- std::string get_enum_class_name(t_type* type);
+ std::string get_enum_class_name(t_type* type) override;
bool field_has_default(t_field* tfield) { return tfield->get_value() != NULL; }
@@ -422,7 +422,7 @@
+ ((async_) ? "using System.Threading.Tasks;\n" : "") + "using Thrift;\n"
+ "using Thrift.Collections;\n" + ((serialize_ || wcf_) ? "#if !SILVERLIGHT\n" : "")
+ ((serialize_ || wcf_) ? "using System.Xml.Serialization;\n" : "")
- + ((serialize_ || wcf_) ? "#endif\n" : "") + (wcf_ ? "//using System.ServiceModel;\n" : "")
+ + ((serialize_ || wcf_) ? "#endif\n" : "")
+ "using System.Runtime.Serialization;\n";
}
@@ -903,7 +903,10 @@
// make private members with public Properties
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- indent(out) << "private " << declare_field(*m_iter, false, "_") << endl;
+ // if the field is requied, then we use auto-properties
+ if (!field_is_required((*m_iter)) && (!nullable_ || field_has_default((*m_iter)))) {
+ indent(out) << "private " << declare_field(*m_iter, false, "_") << endl;
+ }
}
out << endl;
@@ -1251,10 +1254,10 @@
indent_up();
indent(out) << "public abstract void Write(TProtocol protocol);" << endl;
- indent(out) << "public readonly bool Isset;" << endl;
+ indent(out) << "public readonly int Isset;" << endl;
indent(out) << "public abstract object Data { get; }" << endl;
- indent(out) << "protected " << tunion->get_name() << "(bool isset) {" << endl;
+ indent(out) << "protected " << tunion->get_name() << "(int isset) {" << endl;
indent_up();
indent(out) << "Isset = isset;" << endl;
indent_down();
@@ -1265,7 +1268,7 @@
indent(out) << "public override object Data { get { return null; } }" << endl;
- indent(out) << "public ___undefined() : base(false) {}" << endl << endl;
+ indent(out) << "public ___undefined() : base(0) {}" << endl << endl;
indent(out) << "public override void Write(TProtocol protocol) {" << endl;
indent_up();
@@ -1295,13 +1298,27 @@
void t_csharp_generator::generate_csharp_union_class(std::ostream& out,
t_struct* tunion,
t_field* tfield) {
+ indent(out) << "public " << type_name(tfield->get_type()) << " As_" << tfield->get_name() << endl;
+ indent(out) << "{" << endl;
+ indent_up();
+ indent(out) << "get" << endl;
+ indent(out) << "{" << endl;
+ indent_up();
+ indent(out) << "return (" << tfield->get_key() << " == Isset) ? (" << type_name(tfield->get_type()) << ")Data : default(" << type_name(tfield->get_type()) << ");" << endl;
+ indent_down();
+ indent(out) << "}" << endl;
+ indent_down();
+ indent(out) << "}" << endl
+ << endl;
+
+
indent(out) << "public class " << tfield->get_name() << " : " << tunion->get_name() << " {"
<< endl;
indent_up();
indent(out) << "private " << type_name(tfield->get_type()) << " _data;" << endl;
indent(out) << "public override object Data { get { return _data; } }" << endl;
indent(out) << "public " << tfield->get_name() << "(" << type_name(tfield->get_type())
- << " data) : base(true) {" << endl;
+ << " data) : base("<< tfield->get_key() <<") {" << endl;
indent_up();
indent(out) << "this._data = data;" << endl;
indent_down();
@@ -1475,7 +1492,7 @@
generate_csharp_doc(f_service_, tservice);
if (wcf_) {
- indent(f_service_) << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
+ indent(f_service_) << "[System.ServiceModel.ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
}
indent(f_service_) << "public interface ISync" << extends_iface << " {" << endl;
@@ -1487,12 +1504,12 @@
// if we're using WCF, add the corresponding attributes
if (wcf_) {
- indent(f_service_) << "[OperationContract]" << endl;
+ indent(f_service_) << "[System.ServiceModel.OperationContract]" << endl;
const std::vector<t_field*>& xceptions = (*f_iter)->get_xceptions()->get_members();
vector<t_field*>::const_iterator x_iter;
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
- indent(f_service_) << "[FaultContract(typeof("
+ indent(f_service_) << "[System.ServiceModel.FaultContract(typeof("
+ type_name((*x_iter)->get_type(), false, false) + "Fault))]" << endl;
}
}
@@ -1514,7 +1531,7 @@
generate_csharp_doc(f_service_, tservice);
if (wcf_) {
- indent(f_service_) << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
+ indent(f_service_) << "[System.ServiceModel.ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
}
indent(f_service_) << "public interface IAsync" << extends_iface << " {" << endl;
@@ -1526,12 +1543,12 @@
// if we're using WCF, add the corresponding attributes
if (wcf_) {
- indent(f_service_) << "[OperationContract]" << endl;
+ indent(f_service_) << "[System.ServiceModel.OperationContract]" << endl;
const std::vector<t_field*>& xceptions = (*f_iter)->get_xceptions()->get_members();
vector<t_field*>::const_iterator x_iter;
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
- indent(f_service_) << "[FaultContract(typeof("
+ indent(f_service_) << "[System.ServiceModel.FaultContract(typeof("
+ type_name((*x_iter)->get_type(), false, false) + "Fault))]" << endl;
}
}
@@ -1552,7 +1569,7 @@
generate_csharp_doc(f_service_, tservice);
if (wcf_) {
- indent(f_service_) << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
+ indent(f_service_) << "[System.ServiceModel.ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
}
indent(f_service_) << "public interface Iface" << extends_iface << " {" << endl;
diff --git a/compiler/cpp/src/thrift/generate/t_d_generator.cc b/compiler/cpp/src/thrift/generate/t_d_generator.cc
index df56cfc..56519e4 100644
--- a/compiler/cpp/src/thrift/generate/t_d_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_d_generator.cc
@@ -71,7 +71,7 @@
}
protected:
- virtual void init_generator() {
+ void init_generator() override {
// Make output directory
MKDIR(get_out_dir().c_str());
@@ -102,20 +102,20 @@
// Include type modules from other imported programs.
const vector<t_program*>& includes = program_->get_includes();
- for (size_t i = 0; i < includes.size(); ++i) {
- f_types_ << "public import " << render_package(*(includes[i])) << includes[i]->get_name()
+ for (auto include : includes) {
+ f_types_ << "public import " << render_package(*include) << include->get_name()
<< "_types;" << endl;
}
if (!includes.empty())
f_types_ << endl;
}
- virtual void close_generator() {
+ void close_generator() override {
// Close output file
f_types_.close();
}
- virtual void generate_consts(std::vector<t_const*> consts) {
+ void generate_consts(std::vector<t_const*> consts) override {
if (!consts.empty()) {
string f_consts_name = package_dir_ + program_name_ + "_constants.d";
ofstream_with_content_based_conditional_update f_consts;
@@ -159,13 +159,13 @@
}
}
- virtual void generate_typedef(t_typedef* ttypedef) {
+ void generate_typedef(t_typedef* ttypedef) override {
this->emit_doc(ttypedef, f_types_);
f_types_ << indent() << "alias " << render_type_name(ttypedef->get_type()) << " "
<< ttypedef->get_symbolic() << ";" << endl << endl;
}
- virtual void generate_enum(t_enum* tenum) {
+ void generate_enum(t_enum* tenum) override {
vector<t_enum_value*> constants = tenum->get_constants();
this->emit_doc(tenum, f_types_);
@@ -188,15 +188,15 @@
f_types_ << endl;
}
- virtual void generate_struct(t_struct* tstruct) {
+ void generate_struct(t_struct* tstruct) override {
print_struct_definition(f_types_, tstruct, false);
}
- virtual void generate_xception(t_struct* txception) {
+ void generate_xception(t_struct* txception) override {
print_struct_definition(f_types_, txception, true);
}
- virtual void generate_service(t_service* tservice) {
+ void generate_service(t_service* tservice) override {
string svc_name = tservice->get_name();
// Service implementation file includes
diff --git a/compiler/cpp/src/thrift/generate/t_dart_generator.cc b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
index 414c333..fbbb9e6 100644
--- a/compiler/cpp/src/thrift/generate/t_dart_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
@@ -121,25 +121,25 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
void export_class_to_library(string file_name, string class_name);
void generate_dart_library();
void generate_dart_pubspec();
- void generate_consts(std::vector<t_const*> consts);
+ void generate_consts(std::vector<t_const*> consts) override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
void print_const_value(std::ostream& out,
std::string name,
@@ -359,8 +359,8 @@
// add imports for included thrift files
const vector<t_program*>& includes = program_->get_includes();
- for (size_t i = 0; i < includes.size(); ++i) {
- string include_name = find_library_name(includes[i]);
+ for (auto include : includes) {
+ string include_name = find_library_name(include);
string named_import = "t_" + include_name;
if (package_prefix_.empty()) {
imports += "import 'package:" + include_name + "/" + include_name + ".dart' as " + named_import + ";" + endl;
@@ -423,7 +423,7 @@
indent(f_pubspec) << "environment:" << endl;
indent_up();
- indent(f_pubspec) << "sdk: ^1.12.0" << endl;
+ indent(f_pubspec) << "sdk: '>=1.24.3 <3.0.0'" << endl;
indent_down();
f_pubspec << endl;
@@ -438,15 +438,15 @@
indent_down();
} else {
const vector<std::string> lines = split(pubspec_lib_, '|');
- for (size_t line_index = 0; line_index < lines.size(); line_index++) {
- indent(f_pubspec) << lines[line_index] << endl;
+ for (const auto & line : lines) {
+ indent(f_pubspec) << line << endl;
}
}
// add included thrift files as dependencies
const vector<t_program*>& includes = program_->get_includes();
- for (size_t i = 0; i < includes.size(); ++i) {
- string include_name = find_library_name(includes[i]);
+ for (auto include : includes) {
+ string include_name = find_library_name(include);
indent(f_pubspec) << include_name << ":" << endl;
indent_up();
indent(f_pubspec) << "path: ../" << include_name << endl;
@@ -2432,9 +2432,7 @@
bool is_first = true;
bool was_previous_char_upper = false;
- for (string::iterator iter = name.begin(); iter != name.end(); ++iter) {
- string::value_type character = (*iter);
-
+ for (char character : name) {
bool is_upper = isupper(character);
if (is_upper && !is_first && !was_previous_char_upper) {
diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
index 8bd77e8..4a2ebda 100644
--- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
@@ -89,17 +89,17 @@
escape_['\''] = "''";
}
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
- void generate_consts(std::vector<t_const*> consts);
+ void generate_consts(std::vector<t_const*> consts) override;
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_forward_declaration(t_struct* tstruct);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_forward_declaration(t_struct* tstruct) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
void generate_property(ostream& out, t_field* tfield, bool isPublic, bool is_xception);
void generate_property_writer_(ostream& out, t_field* tfield, bool isPublic);
@@ -343,7 +343,7 @@
void write_struct(std::string line);
void write_service(std::string line);
- virtual std::string autogen_comment() {
+ std::string autogen_comment() override {
return std::string("(**\n") + " * Autogenerated by Thrift Compiler (" + THRIFT_VERSION + ")\n"
+ " *\n" + " * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n"
+ " *)\n";
@@ -670,10 +670,8 @@
delphi_reserved_method["instancesize"] = 1;
delphi_reserved_method["inheritsfrom"] = 1;
delphi_reserved_method["methodaddress"] = 1;
- delphi_reserved_method["methodaddress"] = 1;
delphi_reserved_method["methodname"] = 1;
delphi_reserved_method["fieldaddress"] = 1;
- delphi_reserved_method["fieldaddress"] = 1;
delphi_reserved_method["getinterface"] = 1;
delphi_reserved_method["getinterfaceentry"] = 1;
delphi_reserved_method["getinterfacetable"] = 1;
@@ -759,9 +757,9 @@
string unitname, nsname;
const vector<t_program*>& includes = program_->get_includes();
- for (size_t i = 0; i < includes.size(); ++i) {
- unitname = includes[i]->get_name();
- nsname = includes[i]->get_namespace("delphi");
+ for (auto include : includes) {
+ unitname = include->get_name();
+ nsname = include->get_namespace("delphi");
if ("" != nsname) {
unitname = normalize_name(nsname);
}
@@ -788,7 +786,7 @@
std::string f_name = get_out_dir() + "/" + unitname + ".pas";
ofstream_with_content_based_conditional_update f_all;
- f_all.open(f_name.c_str());
+ f_all.open(f_name);
f_all << autogen_comment() << endl;
generate_delphi_doc(f_all, program_);
@@ -1745,7 +1743,7 @@
if (is_exception && (!is_x_factory)) {
out << "TException";
} else {
- out << "TInterfacedObject, IBase, " << struct_intf_name;
+ out << "TInterfacedObject, IBase, ISupportsToString, " << struct_intf_name;
}
out << ")" << endl;
@@ -3951,8 +3949,10 @@
<< ".Append('<null>') else " << tmp_sb << ".Append( Self."
<< prop_name((*f_iter), is_exception) << ".ToString());" << endl;
} else if (ttype->is_enum()) {
- indent_impl(out) << tmp_sb << ".Append(System.Integer( Self." << prop_name((*f_iter), is_exception)
- << "));" << endl;
+ indent_impl(out) << tmp_sb << ".Append(EnumUtils<"
+ << type_name(ttype, false, true, false, false)
+ << ">.ToString( System.Ord( Self."
+ << prop_name((*f_iter), is_exception) << ")));" << endl;
} else {
indent_impl(out) << tmp_sb << ".Append( Self." << prop_name((*f_iter), is_exception) << ");"
<< endl;
diff --git a/compiler/cpp/src/thrift/generate/t_erl_generator.cc b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
index 587133f..910a38a 100644
--- a/compiler/cpp/src/thrift/generate/t_erl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
@@ -83,19 +83,19 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
void generate_member_type(std::ostream& out, t_type* type);
void generate_member_value(std::ostream& out, t_type* type, t_const_value* value);
@@ -295,7 +295,8 @@
* Boilerplate at beginning and end of header files
*/
void t_erl_generator::hrl_header(ostream& out, string name) {
- out << "-ifndef(_" << name << "_included)." << endl << "-define(_" << name << "_included, yeah)."
+ out << erl_autogen_comment() << endl
+ << "-ifndef(_" << name << "_included)." << endl << "-define(_" << name << "_included, yeah)."
<< endl;
}
@@ -310,8 +311,8 @@
string t_erl_generator::render_includes() {
const vector<t_program*>& includes = program_->get_includes();
string result = "";
- for (size_t i = 0; i < includes.size(); ++i) {
- result += "-include(\"" + make_safe_for_module_name(includes[i]->get_name())
+ for (auto include : includes) {
+ result += "-include(\"" + make_safe_for_module_name(include->get_name())
+ "_types.hrl\").\n";
}
if (includes.size() > 0) {
@@ -415,7 +416,6 @@
}
void t_erl_generator::generate_type_metadata(std::string function_name, vector<string> names) {
- vector<string>::iterator s_iter;
size_t num_structs = names.size();
indent(f_types_file_) << function_name << "() ->\n";
@@ -947,7 +947,6 @@
void t_erl_generator::generate_service_metadata(t_service* tservice) {
export_string("function_names", 0);
vector<t_function*> functions = tservice->get_functions();
- vector<t_function*>::iterator f_iter;
size_t num_functions = functions.size();
indent(f_service_) << "function_names() -> " << endl;
@@ -1278,6 +1277,6 @@
THRIFT_REGISTER_GENERATOR(
erl,
"Erlang",
- " legacynames: Output files retain naming conventions of Thrift 0.9.1 and earlier.\n"
- " maps: Generate maps instead of dicts.\n"
- " otp16: Generate non-namespaced dict and set instead of dict:dict and sets:set.\n")
+ " legacynames: Output files retain naming conventions of Thrift 0.9.1 and earlier.\n"
+ " maps: Generate maps instead of dicts.\n"
+ " otp16: Generate non-namespaced dict and set instead of dict:dict and sets:set.\n")
diff --git a/compiler/cpp/src/thrift/generate/t_generator_registry.h b/compiler/cpp/src/thrift/generate/t_generator_registry.h
index 1f02167..d27f710 100644
--- a/compiler/cpp/src/thrift/generate/t_generator_registry.h
+++ b/compiler/cpp/src/thrift/generate/t_generator_registry.h
@@ -35,7 +35,7 @@
const std::string& long_name,
const std::string& documentation);
- virtual ~t_generator_factory() {}
+ virtual ~t_generator_factory() = default;
virtual t_generator* get_generator(
// The program to generate.
@@ -65,13 +65,13 @@
const std::string& documentation)
: t_generator_factory(short_name, long_name, documentation) {}
- virtual t_generator* get_generator(t_program* program,
+ t_generator* get_generator(t_program* program,
const std::map<std::string, std::string>& parsed_options,
- const std::string& option_string) {
+ const std::string& option_string) override {
return new generator(program, parsed_options, option_string);
}
- virtual bool is_valid_namespace(const std::string& sub_namespace) {
+ bool is_valid_namespace(const std::string& sub_namespace) override {
return generator::is_valid_namespace(sub_namespace);
}
};
diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.cc b/compiler/cpp/src/thrift/generate/t_go_generator.cc
index 5ada4fa..66bb653 100644
--- a/compiler/cpp/src/thrift/generate/t_go_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_go_generator.cc
@@ -105,19 +105,19 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
std::string render_const_value(t_type* type, t_const_value* value, const string& name, bool opt = false);
@@ -743,10 +743,10 @@
// Make output files
f_types_name_ = package_dir_ + "/" + program_name_ + ".go";
- f_types_.open(f_types_name_.c_str());
+ f_types_.open(f_types_name_);
f_consts_name_ = package_dir_ + "/" + program_name_ + "-consts.go";
- f_consts_.open(f_consts_name_.c_str());
+ f_consts_.open(f_consts_name_);
// Print header
f_types_ << go_autogen_comment() << go_package() << render_includes(false);
@@ -771,12 +771,12 @@
unused_protection = "";
string local_namespace = program_->get_namespace("go");
- for (size_t i = 0; i < includes.size(); ++i) {
- if (!local_namespace.empty() && local_namespace == includes[i]->get_namespace("go")) {
+ for (auto include : includes) {
+ if (!local_namespace.empty() && local_namespace == include->get_namespace("go")) {
continue;
}
- string go_module = get_real_go_module(includes[i]);
+ string go_module = get_real_go_module(include);
size_t found = 0;
for (size_t j = 0; j < go_module.size(); j++) {
// Import statement uses slashes ('/') in namespace
@@ -803,12 +803,12 @@
string unused_prot = "";
string local_namespace = program_->get_namespace("go");
- for (size_t i = 0; i < includes.size(); ++i) {
- if (!local_namespace.empty() && local_namespace == includes[i]->get_namespace("go")) {
+ for (auto include : includes) {
+ if (!local_namespace.empty() && local_namespace == include->get_namespace("go")) {
continue;
}
- string go_module = get_real_go_module(includes[i]);
+ string go_module = get_real_go_module(include);
size_t found = 0;
for (size_t j = 0; j < go_module.size(); j++) {
// Import statement uses slashes ('/') in namespace
@@ -1255,15 +1255,14 @@
bool is_args_or_result) {
out << publicize(type_name(tstruct), is_args_or_result) << "{";
const vector<t_field*>& members = tstruct->get_members();
- for (vector<t_field*>::const_iterator m_iter = members.begin(); m_iter != members.end();
- ++m_iter) {
- bool pointer_field = is_pointer_field(*m_iter);
+ for (auto member : members) {
+ bool pointer_field = is_pointer_field(member);
string publicized_name;
t_const_value* def_value;
- get_publicized_name_and_def_value(*m_iter, &publicized_name, &def_value);
- if (!pointer_field && def_value != NULL && !omit_initialization(*m_iter)) {
+ get_publicized_name_and_def_value(member, &publicized_name, &def_value);
+ if (!pointer_field && def_value != NULL && !omit_initialization(member)) {
out << endl << indent() << publicized_name << ": "
- << render_field_initial_value(*m_iter, (*m_iter)->get_name(), pointer_field) << ","
+ << render_field_initial_value(member, member->get_name(), pointer_field) << ","
<< endl;
}
}
@@ -1338,7 +1337,13 @@
t_type* fieldType = (*m_iter)->get_type();
string goType = type_to_go_type_with_opt(fieldType, is_pointer_field(*m_iter));
string gotag = "db:\"" + escape_string((*m_iter)->get_name()) + "\" ";
- if ((*m_iter)->get_req() == t_field::T_OPTIONAL) {
+
+ // Only add the `omitempty` tag if this field is optional and has no default value.
+ // Otherwise a proper value like `false` for a bool field will be ommitted from
+ // the JSON output since Go Marshal won't output `zero values`.
+ bool has_default = (*m_iter)->get_value();
+ bool is_optional = (*m_iter)->get_req() == t_field::T_OPTIONAL;
+ if (is_optional && !has_default) {
gotag += "json:\"" + escape_string((*m_iter)->get_name()) + ",omitempty\"";
} else {
gotag += "json:\"" + escape_string((*m_iter)->get_name()) + "\"";
@@ -2153,7 +2158,6 @@
<< (*f_iter)->get_name() << "(";
t_struct* arg_struct = (*f_iter)->get_arglist();
const std::vector<t_field*>& args = arg_struct->get_members();
- vector<t_field*>::const_iterator a_iter;
std::vector<t_field*>::size_type num_args = args.size();
bool first = true;
@@ -2308,7 +2312,6 @@
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
t_struct* arg_struct = (*f_iter)->get_arglist();
const std::vector<t_field*>& args = arg_struct->get_members();
- vector<t_field*>::const_iterator a_iter;
std::vector<t_field*>::size_type num_args = args.size();
string funcName((*f_iter)->get_name());
string pubName(publicize(funcName));
@@ -2693,7 +2696,6 @@
// t_struct* xs = tfunction->get_xceptions();
// const std::vector<t_field*>& xceptions = xs->get_members();
- vector<t_field*>::const_iterator x_iter;
f_types_ << indent() << "type " << processorName << " struct {" << endl;
f_types_ << indent() << " handler " << publicize(tservice->get_name()) << endl;
f_types_ << indent() << "}" << endl << endl;
diff --git a/compiler/cpp/src/thrift/generate/t_gv_generator.cc b/compiler/cpp/src/thrift/generate/t_gv_generator.cc
index 7f8301a..2c0acf9 100644
--- a/compiler/cpp/src/thrift/generate/t_gv_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_gv_generator.cc
@@ -67,17 +67,17 @@
/**
* Init and end of generator
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_service(t_service* tservice) override;
protected:
/**
diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
index 3b88c4d..13f2cd1 100644
--- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
@@ -74,20 +74,20 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
- void generate_consts(std::vector<t_const*> consts);
+ void generate_consts(std::vector<t_const*> consts) override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
void print_const_value(std::ostream& out,
std::string name,
@@ -190,7 +190,7 @@
std::string function_signature_normal(t_function* tfunction);
std::string argument_list(t_struct* tstruct);
std::string type_to_enum(t_type* ttype);
- std::string get_enum_class_name(t_type* type);
+ std::string get_enum_class_name(t_type* type) override;
string generate_service_method_onsuccess(t_function* tfunction, bool as_type, bool omit_name);
void generate_service_method_signature_callback(t_function* tfunction, bool is_interface);
void generate_service_method_signature_normal(t_function* tfunction, bool is_interface);
@@ -2884,9 +2884,7 @@
bool is_first = true;
bool was_previous_char_upper = false;
- for (string::iterator iter = name.begin(); iter != name.end(); ++iter) {
- string::value_type character = (*iter);
-
+ for (char character : name) {
bool is_upper = isupper(character);
if (is_upper && !is_first && !was_previous_char_upper) {
diff --git a/compiler/cpp/src/thrift/generate/t_hs_generator.cc b/compiler/cpp/src/thrift/generate/t_hs_generator.cc
index ce7cd0c..a59dee5 100644
--- a/compiler/cpp/src/thrift/generate/t_hs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_hs_generator.cc
@@ -66,18 +66,18 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
string render_const_value(t_type* type, t_const_value* value);
@@ -261,8 +261,8 @@
"import qualified Thrift.Arbitraries as T\n"
"\n");
- for (size_t i = 0; i < includes.size(); ++i)
- result += "import qualified " + capitalize(includes[i]->get_name()) + "_Types\n";
+ for (auto include : includes)
+ result += "import qualified " + capitalize(include->get_name()) + "_Types\n";
if (includes.size() > 0)
result += "\n";
@@ -407,14 +407,13 @@
} else if (type->is_enum()) {
t_enum* tenum = (t_enum*)type;
vector<t_enum_value*> constants = tenum->get_constants();
- for (vector<t_enum_value*>::iterator c_iter = constants.begin(); c_iter != constants.end();
- ++c_iter) {
- int val = (*c_iter)->get_value();
+ for (auto & constant : constants) {
+ int val = constant->get_value();
if (val == value->get_integer()) {
t_program* prog = type->get_program();
if (prog != NULL && prog != program_)
out << capitalize(prog->get_name()) << "_Types.";
- out << capitalize((*c_iter)->get_name());
+ out << capitalize(constant->get_name());
break;
}
}
@@ -427,21 +426,18 @@
const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
bool first = true;
- for (map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter = val.begin();
- v_iter != val.end();
- ++v_iter) {
+ for (auto v_iter : val) {
t_field* field = NULL;
- for (vector<t_field*>::const_iterator f_iter = fields.begin(); f_iter != fields.end();
- ++f_iter)
- if ((*f_iter)->get_name() == v_iter->first->get_string())
- field = (*f_iter);
+ for (auto f_iter : fields)
+ if (f_iter->get_name() == v_iter.first->get_string())
+ field = f_iter;
if (field == NULL)
- throw "type error: " + cname + " has no field " + v_iter->first->get_string();
+ throw "type error: " + cname + " has no field " + v_iter.first->get_string();
- string fname = v_iter->first->get_string();
- string const_value = render_const_value(field->get_type(), v_iter->second);
+ string fname = v_iter.first->get_string();
+ string const_value = render_const_value(field->get_type(), v_iter.second);
out << (first ? "" : ", ");
out << field_name(cname, fname) << " = ";
@@ -543,21 +539,20 @@
if (members.size() > 0) {
indent_up();
bool first = true;
- for (vector<t_field*>::const_iterator m_iter = members.begin(); m_iter != members.end();
- ++m_iter) {
+ for (auto member : members) {
if (first) {
indent(out) << "{ ";
first = false;
} else {
indent(out) << ", ";
}
- string mname = (*m_iter)->get_name();
+ string mname = member->get_name();
out << field_name(tname, mname) << " :: ";
- if ((*m_iter)->get_req() == t_field::T_OPTIONAL
- || ((t_type*)(*m_iter)->get_type())->is_xception()) {
+ if (member->get_req() == t_field::T_OPTIONAL
+ || ((t_type*)member->get_type())->is_xception()) {
out << "P.Maybe ";
}
- out << render_hs_type((*m_iter)->get_type(), true) << endl;
+ out << render_hs_type(member->get_type(), true) << endl;
}
indent(out) << "}";
indent_down();
@@ -571,9 +566,8 @@
indent(out) << "instance H.Hashable " << tname << " where" << endl;
indent_up();
indent(out) << "hashWithSalt salt record = salt";
- for (vector<t_field*>::const_iterator m_iter = members.begin(); m_iter != members.end();
- ++m_iter) {
- string mname = (*m_iter)->get_name();
+ for (auto member : members) {
+ string mname = member->get_name();
indent(out) << " `H.hashWithSalt` " << field_name(tname, mname) << " record";
}
indent(out) << endl;
@@ -590,7 +584,6 @@
string tname = type_name(tstruct);
string name = tstruct->get_name();
const vector<t_field*>& members = tstruct->get_members();
- vector<t_field*>::const_iterator m_iter;
indent(out) << "instance QC.Arbitrary " << tname << " where " << endl;
indent_up();
@@ -601,8 +594,7 @@
indent_up();
indent_up();
bool first = true;
- for (vector<t_field*>::const_iterator m_iter = members.begin(); m_iter != members.end();
- ++m_iter) {
+ for (auto member : members) {
if (first) {
first = false;
out << " ";
@@ -610,8 +602,8 @@
indent(out) << "`M.ap`";
}
out << "(";
- if ((*m_iter)->get_req() == t_field::T_OPTIONAL
- || ((t_type*)(*m_iter)->get_type())->is_xception()) {
+ if (member->get_req() == t_field::T_OPTIONAL
+ || ((t_type*)member->get_type())->is_xception()) {
out << "M.liftM P.Just ";
}
out << "QC.arbitrary)" << endl;
@@ -626,15 +618,14 @@
indent(out) << " | P.otherwise = M.catMaybes" << endl;
indent_up();
first = true;
- for (vector<t_field*>::const_iterator m_iter = members.begin(); m_iter != members.end();
- ++m_iter) {
+ for (auto member : members) {
if (first) {
first = false;
indent(out) << "[ ";
} else {
indent(out) << ", ";
}
- string fname = field_name(tname, (*m_iter)->get_name());
+ string fname = field_name(tname, member->get_name());
out << "if obj == default_" << tname;
out << "{" << fname << " = " << fname << " obj} ";
out << "then P.Nothing ";
@@ -654,7 +645,6 @@
*/
void t_hs_generator::generate_hs_struct_reader(ostream& out, t_struct* tstruct) {
const vector<t_field*>& fields = tstruct->get_members();
- vector<t_field*>::const_iterator f_iter;
string sname = type_name(tstruct);
string id = tmp("_id");
@@ -667,10 +657,10 @@
bool first = true;
// Generate deserialization code for known cases
- for (vector<t_field*>::const_iterator f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- int32_t key = (*f_iter)->get_key();
- string etype = type_to_enum((*f_iter)->get_type());
- string fname = (*f_iter)->get_name();
+ for (auto field : fields) {
+ int32_t key = field->get_key();
+ string etype = type_to_enum(field->get_type());
+ string fname = field->get_name();
if (first) {
first = false;
@@ -682,11 +672,11 @@
indent(out) << field_name(sname, fname) << " = ";
out << "P.maybe (";
- if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
+ if (field->get_req() == t_field::T_REQUIRED) {
out << "P.error \"Missing required field: " << fname << "\"";
} else {
- if (((*f_iter)->get_req() == t_field::T_OPTIONAL
- || ((t_type*)(*f_iter)->get_type())->is_xception()) && (*f_iter)->get_value() == NULL) {
+ if ((field->get_req() == t_field::T_OPTIONAL
+ || ((t_type*)field->get_type())->is_xception()) && field->get_value() == NULL) {
out << "P.Nothing";
} else {
out << field_name(sname, fname) << " default_" << sname;
@@ -695,10 +685,10 @@
out << ") ";
out << "(\\(_," << val << ") -> ";
- if ((*f_iter)->get_req() == t_field::T_OPTIONAL
- || ((t_type*)(*f_iter)->get_type())->is_xception())
+ if (field->get_req() == t_field::T_OPTIONAL
+ || ((t_type*)field->get_type())->is_xception())
out << "P.Just ";
- generate_deserialize_field(out, *f_iter, val);
+ generate_deserialize_field(out, field, val);
out << ")";
out << " (Map.lookup (" << key << ") fields)";
}
@@ -725,7 +715,6 @@
void t_hs_generator::generate_hs_struct_writer(ostream& out, t_struct* tstruct) {
string name = type_name(tstruct);
const vector<t_field*>& fields = tstruct->get_sorted_members();
- vector<t_field*>::const_iterator f_iter;
string str = tmp("_str");
string f = tmp("_f");
string v = tmp("_v");
@@ -736,8 +725,8 @@
// Get Exceptions
bool hasExn = false;
- for (vector<t_field*>::const_iterator f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- if (((t_type*)(*f_iter)->get_type())->is_xception()) {
+ for (auto field : fields) {
+ if (((t_type*)field->get_type())->is_xception()) {
hasExn = true;
break;
}
@@ -748,19 +737,18 @@
out << endl;
indent(out) << "(let exns = M.catMaybes ";
indent_up();
- for (vector<t_field*>::const_iterator f_iter = fields.begin(); f_iter != fields.end();
- ++f_iter) {
- if (((t_type*)(*f_iter)->get_type())->is_xception()) {
+ for (auto field : fields) {
+ if (((t_type*)field->get_type())->is_xception()) {
if (isfirst) {
out << "[ ";
isfirst = false;
} else {
out << ", ";
}
- string mname = (*f_iter)->get_name();
- int32_t key = (*f_iter)->get_key();
+ string mname = field->get_name();
+ int32_t key = field->get_key();
out << "(\\" << v << " -> (" << key << ", (\"" << mname << "\",";
- generate_serialize_type(out, (*f_iter)->get_type(), v);
+ generate_serialize_type(out, field->get_type(), v);
out << "))) <$> " << field_name(name, mname) << " record";
}
}
@@ -777,7 +765,7 @@
out << "M.catMaybes" << endl;
// Get the Rest
isfirst = true;
- for (vector<t_field*>::const_iterator f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+ for (auto field : fields) {
// Write field header
if (isfirst) {
indent(out) << "[ ";
@@ -785,19 +773,19 @@
} else {
indent(out) << ", ";
}
- string mname = (*f_iter)->get_name();
- int32_t key = (*f_iter)->get_key();
+ string mname = field->get_name();
+ int32_t key = field->get_key();
out << "(\\";
out << v << " -> ";
- if ((*f_iter)->get_req() != t_field::T_OPTIONAL
- && !((t_type*)(*f_iter)->get_type())->is_xception()) {
+ if (field->get_req() != t_field::T_OPTIONAL
+ && !((t_type*)field->get_type())->is_xception()) {
out << "P.Just ";
}
out << "(" << key << ", (\"" << mname << "\",";
- generate_serialize_type(out, (*f_iter)->get_type(), v);
+ generate_serialize_type(out, field->get_type(), v);
out << "))) ";
- if ((*f_iter)->get_req() != t_field::T_OPTIONAL
- && !((t_type*)(*f_iter)->get_type())->is_xception()) {
+ if (field->get_req() != t_field::T_OPTIONAL
+ && !((t_type*)field->get_type())->is_xception()) {
out << "$";
} else {
out << "<$>";
@@ -909,19 +897,18 @@
void t_hs_generator::generate_hs_typemap(ostream& out, t_struct* tstruct) {
string name = type_name(tstruct);
const vector<t_field*>& fields = tstruct->get_sorted_members();
- vector<t_field*>::const_iterator f_iter;
indent(out) << "typemap_" << name << " :: T.TypeMap" << endl;
indent(out) << "typemap_" << name << " = Map.fromList [";
bool first = true;
- for (vector<t_field*>::const_iterator f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- string mname = (*f_iter)->get_name();
+ for (auto field : fields) {
+ string mname = field->get_name();
if (!first) {
out << ",";
}
- t_type* type = get_true_type((*f_iter)->get_type());
- int32_t key = (*f_iter)->get_key();
+ t_type* type = get_true_type(field->get_type());
+ int32_t key = field->get_key();
out << "(" << key << ",(\"" << mname << "\"," << type_to_enum(type) << "))";
first = false;
}
@@ -941,19 +928,19 @@
indent(out) << fname << " = " << name << "{" << endl;
indent_up();
bool first = true;
- for (vector<t_field*>::const_iterator f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- string mname = (*f_iter)->get_name();
+ for (auto field : fields) {
+ string mname = field->get_name();
if (first) {
first = false;
} else {
out << "," << endl;
}
- t_type* type = get_true_type((*f_iter)->get_type());
- t_const_value* value = (*f_iter)->get_value();
+ t_type* type = get_true_type(field->get_type());
+ t_const_value* value = field->get_value();
indent(out) << field_name(name, mname) << " = ";
- if ((*f_iter)->get_req() == t_field::T_OPTIONAL
- || ((t_type*)(*f_iter)->get_type())->is_xception()) {
+ if (field->get_req() == t_field::T_OPTIONAL
+ || ((t_type*)field->get_type())->is_xception()) {
if (value == NULL) {
out << "P.Nothing";
} else {
@@ -1091,13 +1078,12 @@
indent(f_client_) << "write_" << argsname << " op (" << argsname << "{";
bool first = true;
- for (vector<t_field*>::const_iterator fld_iter = fields.begin(); fld_iter != fields.end();
- ++fld_iter) {
- string fieldname = (*fld_iter)->get_name();
+ for (auto field : fields) {
+ string fieldname = field->get_name();
f_client_ << (first ? "" : ",");
f_client_ << field_name(argsname, fieldname) << "=";
- if ((*fld_iter)->get_req() == t_field::T_OPTIONAL
- || ((t_type*)(*fld_iter)->get_type())->is_xception())
+ if (field->get_req() == t_field::T_OPTIONAL
+ || ((t_type*)field->get_type())->is_xception())
f_client_ << "P.Just ";
f_client_ << "arg_" << fieldname;
first = false;
@@ -1127,10 +1113,9 @@
t_struct* xs = (*f_iter)->get_xceptions();
const vector<t_field*>& xceptions = xs->get_members();
- for (vector<t_field*>::const_iterator x_iter = xceptions.begin(); x_iter != xceptions.end();
- ++x_iter) {
+ for (auto xception : xceptions) {
indent(f_client_) << "P.maybe (P.return ()) X.throw ("
- << field_name(resultname, (*x_iter)->get_name()) << " res)" << endl;
+ << field_name(resultname, xception->get_name()) << " res)" << endl;
}
if (!(*f_iter)->get_returntype()->is_void())
@@ -1503,11 +1488,11 @@
string result = "";
const vector<t_field*>& fields = tfunc->get_arglist()->get_members();
- for (vector<t_field*>::const_iterator f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
- if ((*f_iter)->get_req() == t_field::T_OPTIONAL
- || ((t_type*)(*f_iter)->get_type())->is_xception())
+ for (auto field : fields) {
+ if (field->get_req() == t_field::T_OPTIONAL
+ || ((t_type*)field->get_type())->is_xception())
result += "P.Maybe ";
- result += render_hs_type((*f_iter)->get_type(), options);
+ result += render_hs_type(field->get_type(), options);
result += " -> ";
}
diff --git a/compiler/cpp/src/thrift/generate/t_html_generator.cc b/compiler/cpp/src/thrift/generate/t_html_generator.cc
index 8dfa389..b61a712 100644
--- a/compiler/cpp/src/thrift/generate/t_html_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_html_generator.cc
@@ -82,7 +82,7 @@
init_allowed__markup();
}
- void generate_program();
+ void generate_program() override;
void generate_program_toc();
void generate_program_toc_row(t_program* tprog);
void generate_program_toc_rows(t_program* tprog, std::vector<t_program*>& finished);
@@ -101,12 +101,12 @@
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_service(t_service* tservice);
- void generate_xception(t_struct* txception);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_service(t_service* tservice) override;
+ void generate_xception(t_struct* txception) override;
void print_doc(t_doc* tdoc);
int print_type(t_type* ttype);
@@ -127,10 +127,10 @@
*/
void t_html_generator::generate_program_toc() {
f_out_ << "<table class=\"table-bordered table-striped "
- "table-condensed\"><thead><th>Module</th><th>Services</th>"
- << "<th>Data types</th><th>Constants</th></thead>" << endl;
+ "table-condensed\"><thead><tr><th>Module</th><th>Services</th>"
+ << "<th>Data types</th><th>Constants</th></tr></thead><tbody>" << endl;
generate_program_toc_row(program_);
- f_out_ << "</table>" << endl;
+ f_out_ << "</tbody></table>" << endl;
}
/**
@@ -140,16 +140,16 @@
*/
void t_html_generator::generate_program_toc_rows(t_program* tprog,
std::vector<t_program*>& finished) {
- for (vector<t_program*>::iterator iter = finished.begin(); iter != finished.end(); iter++) {
- if (tprog->get_path() == (*iter)->get_path()) {
+ for (auto & iter : finished) {
+ if (tprog->get_path() == iter->get_path()) {
return;
}
}
finished.push_back(tprog);
generate_program_toc_row(tprog);
vector<t_program*> includes = tprog->get_includes();
- for (vector<t_program*>::iterator iter = includes.begin(); iter != includes.end(); iter++) {
- generate_program_toc_rows(*iter, finished);
+ for (auto & include : includes) {
+ generate_program_toc_rows(include, finished);
}
}
@@ -176,9 +176,8 @@
+ "\">" + fn_name + "</a></li>";
fn_html.insert(pair<string, string>(fn_name, html));
}
- for (map<string, string>::iterator html_iter = fn_html.begin(); html_iter != fn_html.end();
- html_iter++) {
- f_out_ << html_iter->second << endl;
+ for (auto & html_iter : fn_html) {
+ f_out_ << html_iter.second << endl;
}
f_out_ << "</ul>" << endl;
}
@@ -220,9 +219,8 @@
data_types.insert(pair<string, string>(name, html));
}
}
- for (map<string, string>::iterator dt_iter = data_types.begin(); dt_iter != data_types.end();
- dt_iter++) {
- f_out_ << dt_iter->second << "<br/>" << endl;
+ for (auto & data_type : data_types) {
+ f_out_ << data_type.second << "<br/>" << endl;
}
f_out_ << "</td>" << endl << "<td>";
if (!tprog->get_consts().empty()) {
@@ -235,12 +233,11 @@
+ "</a></code>";
const_html.insert(pair<string, string>(name, html));
}
- for (map<string, string>::iterator con_iter = const_html.begin(); con_iter != const_html.end();
- con_iter++) {
- f_out_ << con_iter->second << "<br/>" << endl;
+ for (auto & con_iter : const_html) {
+ f_out_ << con_iter.second << "<br/>" << endl;
}
}
- f_out_ << "</code></td>" << endl << "</tr>";
+ f_out_ << "</td>" << endl << "</tr>";
}
/**
@@ -253,9 +250,8 @@
current_file_ = program_->get_name() + ".html";
string fname = get_out_dir() + current_file_;
f_out_.open(fname.c_str());
- f_out_ << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"" << endl;
- f_out_ << " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" << endl;
- f_out_ << "<html xmlns=\"http://www.w3.org/1999/xhtml\">" << endl;
+ f_out_ << "<!DOCTYPE html>" << endl;
+ f_out_ << "<html lang=\"en\">" << endl;
f_out_ << "<head>" << endl;
f_out_ << "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />" << endl;
generate_style_tag();
@@ -271,9 +267,9 @@
f_out_ << "<hr/><h2 id=\"Constants\">Constants</h2>" << endl;
vector<t_const*> consts = program_->get_consts();
f_out_ << "<table class=\"table-bordered table-striped table-condensed\">";
- f_out_ << "<thead><th>Constant</th><th>Type</th><th>Value</th></thead>" << endl;
+ f_out_ << "<thead><tr><th>Constant</th><th>Type</th><th>Value</th></tr></thead><tbody>" << endl;
generate_consts(consts);
- f_out_ << "</table>";
+ f_out_ << "</tbody></table>";
}
if (!program_->get_enums().empty()) {
@@ -335,16 +331,16 @@
current_file_ = "index.html";
string index_fname = get_out_dir() + current_file_;
f_out_.open(index_fname.c_str());
- f_out_ << "<html><head>" << endl;
+ f_out_ << "<!DOCTYPE html>" << endl << "<html lang=\"en\"><head>" << endl;
generate_style_tag();
f_out_ << "<title>All Thrift declarations</title></head><body>" << endl
<< "<div class=\"container-fluid\">" << endl << "<h1>All Thrift declarations</h1>" << endl;
f_out_ << "<table class=\"table-bordered table-striped "
- "table-condensed\"><thead><th>Module</th><th>Services</th><th>Data types</th>"
- << "<th>Constants</th></thead>" << endl;
+ "table-condensed\"><thead><tr><th>Module</th><th>Services</th><th>Data types</th>"
+ << "<th>Constants</th></tr></thead><tbody>" << endl;
vector<t_program*> programs;
generate_program_toc_rows(program_, programs);
- f_out_ << "</table>" << endl;
+ f_out_ << "</tbody></table>" << endl;
f_out_ << "</div></body></html>" << endl;
f_out_.close();
}
@@ -573,8 +569,8 @@
if (first_white != string::npos) {
tag_key.erase(first_white);
}
- for (std::string::size_type i = 0; i < tag_key.length(); ++i) {
- tag_key[i] = tolower(tag_key[i]);
+ for (char & i : tag_key) {
+ i = tolower(i);
}
if (allowed_markup.find(tag_key) != allowed_markup.end()) {
result << "<" << tag_content << ">";
@@ -861,14 +857,14 @@
f_out_ << "<br/><h4 id=\"Parameters_" << service_name_ << "_" << tfunction->get_name()
<< "\">Parameters</h4>" << endl;
f_out_ << "<table class=\"table-bordered table-striped table-condensed\">";
- f_out_ << "<thead><th>Name</th><th>Description</th></thead>";
+ f_out_ << "<thead><tr><th>Name</th><th>Description</th></tr></thead><tbody>";
for (; arg_iter != args.end(); arg_iter++) {
f_out_ << "<tr><td>" << (*arg_iter)->get_name();
f_out_ << "</td><td>";
f_out_ << escape_html((*arg_iter)->get_doc());
f_out_ << "</td></tr>" << endl;
}
- f_out_ << "</table>";
+ f_out_ << "</tbody></table>";
}
}
@@ -885,14 +881,14 @@
f_out_ << "<br/><h4 id=\"Exceptions_" << service_name_ << "_" << tfunction->get_name()
<< "\">Exceptions</h4>" << endl;
f_out_ << "<table class=\"table-bordered table-striped table-condensed\">";
- f_out_ << "<thead><th>Type</th><th>Description</th></thead>";
+ f_out_ << "<thead><tr><th>Type</th><th>Description</th></tr></thead><tbody>";
for (; ex_iter != excepts.end(); ex_iter++) {
f_out_ << "<tr><td>" << (*ex_iter)->get_type()->get_name();
f_out_ << "</td><td>";
f_out_ << escape_html((*ex_iter)->get_doc());
f_out_ << "</td></tr>" << endl;
}
- f_out_ << "</table>";
+ f_out_ << "</tbody></table>";
}
}
}
@@ -975,8 +971,8 @@
vector<t_field*> members = tstruct->get_members();
vector<t_field*>::iterator mem_iter = members.begin();
f_out_ << "<table class=\"table-bordered table-striped table-condensed\">";
- f_out_ << "<thead><th>Key</th><th>Field</th><th>Type</th><th>Description</th><th>Requiredness</"
- "th><th>Default value</th></thead>" << endl;
+ f_out_ << "<thead><tr><th>Key</th><th>Field</th><th>Type</th><th>Description</th><th>Requiredness</"
+ "th><th>Default value</th></tr></thead><tbody>" << endl;
for (; mem_iter != members.end(); mem_iter++) {
f_out_ << "<tr><td>" << (*mem_iter)->get_key() << "</td><td>";
f_out_ << (*mem_iter)->get_name();
@@ -1001,7 +997,7 @@
}
f_out_ << "</td></tr>" << endl;
}
- f_out_ << "</table><br/>";
+ f_out_ << "</tbody></table><br/>";
print_doc(tstruct);
f_out_ << "</div>";
}
diff --git a/compiler/cpp/src/thrift/generate/t_java_generator.cc b/compiler/cpp/src/thrift/generate/t_java_generator.cc
index 2c84551..2fb1f1a 100644
--- a/compiler/cpp/src/thrift/generate/t_java_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_java_generator.cc
@@ -122,21 +122,21 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
- void generate_consts(std::vector<t_const*> consts);
+ void generate_consts(std::vector<t_const*> consts) override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_struct(t_struct* tstruct);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_struct(t_struct* tstruct) override;
void generate_union(t_struct* tunion);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
void print_const_value(std::ostream& out,
std::string name,
@@ -4652,9 +4652,7 @@
bool is_first = true;
bool was_previous_char_upper = false;
- for (string::iterator iter = name.begin(); iter != name.end(); ++iter) {
- string::value_type character = (*iter);
-
+ for (char character : name) {
bool is_upper = isupper(character);
if (is_upper && !is_first && !was_previous_char_upper) {
diff --git a/compiler/cpp/src/thrift/generate/t_javame_generator.cc b/compiler/cpp/src/thrift/generate/t_javame_generator.cc
index fa743ca..e1694ab 100644
--- a/compiler/cpp/src/thrift/generate/t_javame_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_javame_generator.cc
@@ -65,21 +65,21 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
- void generate_consts(std::vector<t_const*> consts);
+ void generate_consts(std::vector<t_const*> consts) override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_struct(t_struct* tstruct);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_struct(t_struct* tstruct) override;
void generate_union(t_struct* tunion);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
void print_const_value(std::ostream& out,
std::string name,
@@ -185,13 +185,13 @@
void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
- void generate_java_doc(std::ostream& out, t_field* field);
+ void generate_java_doc(std::ostream& out, t_field* field) override;
- void generate_java_doc(std::ostream& out, t_doc* tdoc);
+ void generate_java_doc(std::ostream& out, t_doc* tdoc) override;
- void generate_java_doc(std::ostream& out, t_function* tdoc);
+ void generate_java_doc(std::ostream& out, t_function* tdoc) override;
- void generate_java_docstring_comment(std::ostream& out, string contents);
+ void generate_java_docstring_comment(std::ostream& out, string contents) override;
void generate_deep_copy_container(std::ostream& out,
std::string source_name_p1,
@@ -221,7 +221,7 @@
std::string function_signature(t_function* tfunction, std::string prefix = "");
std::string argument_list(t_struct* tstruct, bool include_types = true);
std::string type_to_enum(t_type* ttype);
- std::string get_enum_class_name(t_type* type);
+ std::string get_enum_class_name(t_type* type) override;
void generate_struct_desc(ostream& out, t_struct* tstruct);
void generate_field_descs(ostream& out, t_struct* tstruct);
std::string box_type(t_type* type, string value);
@@ -2980,9 +2980,7 @@
bool is_first = true;
bool was_previous_char_upper = false;
- for (string::iterator iter = name.begin(); iter != name.end(); ++iter) {
- string::value_type character = (*iter);
-
+ for (char character : name) {
bool is_upper = isupper(character);
if (is_upper && !is_first && !was_previous_char_upper) {
diff --git a/compiler/cpp/src/thrift/generate/t_js_generator.cc b/compiler/cpp/src/thrift/generate/t_js_generator.cc
index 61782b9..af402a4 100644
--- a/compiler/cpp/src/thrift/generate/t_js_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_js_generator.cc
@@ -41,6 +41,10 @@
using std::vector;
static const string endl = "\n"; // avoid ostream << std::endl flushes
+// largest consecutive integer representable by a double (2 ^ 53 - 1)
+static const int64_t max_safe_integer = 0x1fffffffffffff;
+// smallest consecutive number representable by a double (-2 ^ 53 + 1)
+static const int64_t min_safe_integer = -max_safe_integer;
#include "thrift/generate/t_oop_generator.h"
@@ -117,19 +121,19 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
std::string render_recv_throw(std::string var);
std::string render_recv_return(std::string var);
@@ -200,7 +204,9 @@
std::string js_includes();
std::string ts_includes();
+ std::string ts_service_includes();
std::string render_includes();
+ std::string render_ts_includes();
std::string declare_field(t_field* tfield, bool init = false, bool obj = false);
std::string function_signature(t_function* tfunction,
std::string prefix = "",
@@ -209,7 +215,7 @@
std::string type_to_enum(t_type* ttype);
std::string make_valid_nodeJs_identifier(std::string const& name);
- std::string autogen_comment() {
+ std::string autogen_comment() override {
return std::string("//\n") + "// Autogenerated by Thrift Compiler (" + THRIFT_VERSION + ")\n"
+ "//\n" + "// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n"
+ "//\n";
@@ -282,7 +288,7 @@
* TypeScript Definition File helper functions
*/
- string ts_function_signature(t_function* tfunction, bool include_callback, bool optional_callback);
+ string ts_function_signature(t_function* tfunction, bool include_callback);
string ts_get_type(t_type* type);
/**
@@ -296,7 +302,7 @@
* Returns "declare " if no module was defined.
* @return string
*/
- string ts_declare() { return (ts_module_.empty() ? "declare " : ""); }
+ string ts_declare() { return (ts_module_.empty() ? (gen_node_ ? "declare " : "export declare ") : ""); }
/**
* Returns "?" if the given field is optional or has a default value.
@@ -430,6 +436,8 @@
f_types_ << "if (typeof " << pns << " === 'undefined') {" << endl;
f_types_ << " " << pns << " = {};" << endl;
f_types_ << "}" << endl;
+ f_types_ << "" << "if (typeof module !== 'undefined' && module.exports) {" << endl;
+ f_types_ << " module.exports." << pns << " = " << pns << ";" << endl << "}" << endl;
}
if (gen_ts_) {
ts_module_ = pns;
@@ -448,10 +456,11 @@
if (!gen_es6_) {
result += js_const_type_ + "Q = thrift.Q;\n";
}
+ result += js_const_type_ + "Int64 = require('node-int64');\n";
return result;
}
-
- return "";
+ string result = "if (typeof Int64 === 'undefined' && typeof require === 'function') {\n " + js_const_type_ + "Int64 = require('node-int64');\n}\n";
+ return result;
}
/**
@@ -462,10 +471,24 @@
return string(
"import thrift = require('thrift');\n"
"import Thrift = thrift.Thrift;\n"
- "import Q = thrift.Q;\n");
+ "import Q = thrift.Q;\n"
+ "import Int64 = require('node-int64');");
}
+ return string("import Int64 = require('node-int64');");
+}
- return "";
+/**
+ * Prints service ts imports
+ */
+string t_js_generator::ts_service_includes() {
+ if (gen_node_) {
+ return string(
+ "import thrift = require('thrift');\n"
+ "import Thrift = thrift.Thrift;\n"
+ "import Q = thrift.Q;\n"
+ "import Int64 = require('node-int64');");
+ }
+ return string("import Int64 = require('node-int64');");
}
/**
@@ -476,8 +499,8 @@
if (gen_node_) {
const vector<t_program*>& includes = program_->get_includes();
- for (size_t i = 0; i < includes.size(); ++i) {
- result += js_const_type_ + make_valid_nodeJs_identifier(includes[i]->get_name()) + "_ttypes = require('./" + includes[i]->get_name()
+ for (auto include : includes) {
+ result += js_const_type_ + make_valid_nodeJs_identifier(include->get_name()) + "_ttypes = require('./" + include->get_name()
+ "_types');\n";
}
if (includes.size() > 0) {
@@ -489,6 +512,27 @@
}
/**
+ * Renders all the imports necessary for including another Thrift program
+ */
+string t_js_generator::render_ts_includes() {
+ string result;
+
+ if (!gen_node_) {
+ return result;
+ }
+ const vector<t_program*>& includes = program_->get_includes();
+ for (auto include : includes) {
+ result += "import " + make_valid_nodeJs_identifier(include->get_name()) + "_ttypes = require('./" + include->get_name()
+ + "_types');\n";
+ }
+ if (includes.size() > 0) {
+ result += "\n";
+ }
+
+ return result;
+}
+
+/**
* Close up (or down) some filez.
*/
void t_js_generator::close_generator() {
@@ -593,9 +637,18 @@
case t_base_type::TYPE_I8:
case t_base_type::TYPE_I16:
case t_base_type::TYPE_I32:
- case t_base_type::TYPE_I64:
out << value->get_integer();
break;
+ case t_base_type::TYPE_I64:
+ {
+ int64_t const& integer_value = value->get_integer();
+ if (integer_value <= max_safe_integer && integer_value >= min_safe_integer) {
+ out << "new Int64(" << integer_value << ")";
+ } else {
+ out << "new Int64('" << std::hex << integer_value << std::dec << "')";
+ }
+ }
+ break;
case t_base_type::TYPE_DOUBLE:
if (value->get_type() == t_const_value::CV_INTEGER) {
out << value->get_integer();
@@ -645,8 +698,12 @@
for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
if (v_iter != val.begin())
out << "," << endl;
-
- out << indent() << render_const_value(ktype, v_iter->first);
+
+ if (ktype->is_base_type() && ((t_base_type*)get_true_type(ktype))->get_base() == t_base_type::TYPE_I64){
+ out << indent() << "\"" << v_iter->first->get_integer() << "\"";
+ } else {
+ out << indent() << render_const_value(ktype, v_iter->first);
+ }
out << " : ";
out << render_const_value(vtype, v_iter->second);
@@ -1086,9 +1143,8 @@
f_service_ts_ << "/// <reference path=\"" << tservice->get_extends()->get_name()
<< ".d.ts\" />" << endl;
}
- f_service_ts_ << autogen_comment() << endl;
+ f_service_ts_ << autogen_comment() << endl << ts_includes() << endl << render_ts_includes() << endl;
if (gen_node_) {
- f_service_ts_ << ts_includes() << endl;
f_service_ts_ << "import ttypes = require('./" + program_->get_name() + "_types');" << endl;
// Generate type aliases
// enum
@@ -1119,9 +1175,18 @@
f_service_ts_ << "import " << (*s_iter)->get_name() << " = ttypes."
<< js_namespace(program_) << (*s_iter)->get_name() << endl;
}
+ } else {
+ f_service_ts_ << "import { " << program_->get_name() << " } from \"./" << program_->get_name() << "_types\";" << endl << endl;
}
if (!ts_module_.empty()) {
- f_service_ts_ << "declare module " << ts_module_ << " {";
+ if (gen_node_) {
+ f_service_ts_ << "declare module " << ts_module_ << " {";
+ } else {
+ f_service_ts_ << "declare module \"./" << program_->get_name() << "_types\" {" << endl;
+ indent_up();
+ f_service_ts_ << ts_indent() << "module " << program_->get_name() << " {" << endl;
+ indent_up();
+ }
}
}
@@ -1149,7 +1214,13 @@
f_service_.close();
if (gen_ts_) {
if (!ts_module_.empty()) {
- f_service_ts_ << "}";
+ if (gen_node_) {
+ f_service_ts_ << "}" << endl;
+ } else {
+ indent_down();
+ f_service_ts_ << ts_indent() << "}" << endl;
+ f_service_ts_ << "}" << endl;
+ }
}
f_service_ts_.close();
}
@@ -1174,9 +1245,9 @@
}
f_service_ts_ << "{" << endl;
indent_up();
- f_service_ts_ << ts_indent() << "private _handler: Object;" << endl << endl;
- f_service_ts_ << ts_indent() << "constructor(handler: Object);" << endl;
- f_service_ts_ << ts_indent() << "process(input: Thrift.TJSONProtocol, output: Thrift.TJSONProtocol): void;" << endl;
+ f_service_ts_ << ts_indent() << "private _handler: object;" << endl << endl;
+ f_service_ts_ << ts_indent() << "constructor(handler: object);" << endl;
+ f_service_ts_ << ts_indent() << "process(input: thrift.TProtocol, output: thrift.TProtocol): void;" << endl;
indent_down();
}
} else {
@@ -1280,7 +1351,7 @@
}
if (gen_ts_) {
indent_up();
- f_service_ts_ << ts_indent() << "process_" << tfunction->get_name() << "(seqid: number, input: Thrift.TJSONProtocol, output: Thrift.TJSONProtocol): void;" << endl;
+ f_service_ts_ << ts_indent() << "process_" << tfunction->get_name() << "(seqid: number, input: thrift.TProtocol, output: thrift.TProtocol): void;" << endl;
indent_down();
}
@@ -1369,8 +1440,8 @@
t_struct* exceptions = tfunction->get_xceptions();
if (exceptions) {
const vector<t_field*>& members = exceptions->get_members();
- for (vector<t_field*>::const_iterator it = members.begin(); it != members.end(); ++it) {
- t_type* t = get_true_type((*it)->get_type());
+ for (auto member : members) {
+ t_type* t = get_true_type(member->get_type());
if (t->is_xception()) {
if (!has_exception) {
has_exception = true;
@@ -1433,8 +1504,8 @@
indent(f_service_) << "if ((err === null || typeof err === 'undefined')";
if (has_exception) {
const vector<t_field*>& members = exceptions->get_members();
- for (vector<t_field*>::const_iterator it = members.begin(); it != members.end(); ++it) {
- t_type* t = get_true_type((*it)->get_type());
+ for (auto member : members) {
+ t_type* t = get_true_type(member->get_type());
if (t->is_xception()) {
f_service_ << " || err instanceof " << js_type_namespace(t->get_program()) << t->get_name();
}
@@ -1600,10 +1671,11 @@
indent(f_service_) << "this._seqid = 0;" << endl;
indent(f_service_) << "this._reqs = {};" << endl;
if (gen_ts_) {
- f_service_ts_ << ts_indent() << "private input: Thrift.TJSONProtocol;" << endl << ts_indent()
- << "private output: Thrift.TJSONProtocol;" << endl << ts_indent() << "private seqid: number;"
- << endl << endl << ts_indent()
- << "constructor(input: Thrift.TJSONProtocol, output?: Thrift.TJSONProtocol);"
+ f_service_ts_ << ts_indent() << "private output: thrift.TTransport;" << endl
+ << ts_indent() << "private pClass: thrift.TProtocol;" << endl
+ << ts_indent() << "private _seqid: number;" << endl
+ << endl
+ << ts_indent() << "constructor(output: thrift.TTransport, pClass: { new(trans: thrift.TTransport): thrift.TProtocol });"
<< endl;
}
} else {
@@ -1674,13 +1746,13 @@
if (gen_ts_) {
// function definition without callback
- f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, false, false) << endl;
+ f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, false) << endl;
if (!gen_es6_) {
// overload with callback
- f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true, false) << endl;
+ f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true) << endl;
} else {
// overload with callback
- f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true, true) << endl;
+ f_service_ts_ << ts_print_doc(*f_iter) << ts_indent() << ts_function_signature(*f_iter, true) << endl;
}
}
@@ -2572,10 +2644,12 @@
break;
case t_base_type::TYPE_I16:
case t_base_type::TYPE_I32:
- case t_base_type::TYPE_I64:
case t_base_type::TYPE_DOUBLE:
ts_type = "number";
break;
+ case t_base_type::TYPE_I64:
+ ts_type = "Int64";
+ break;
case t_base_type::TYPE_VOID:
ts_type = "void";
}
@@ -2622,7 +2696,7 @@
* @param bool in-/exclude the callback argument
* @return String of rendered function definition
*/
-std::string t_js_generator::ts_function_signature(t_function* tfunction, bool include_callback, bool optional_callback) {
+std::string t_js_generator::ts_function_signature(t_function* tfunction, bool include_callback) {
string str;
const vector<t_field*>& fields = tfunction->get_arglist()->get_members();
vector<t_field*>::const_iterator f_iter;
@@ -2638,7 +2712,6 @@
}
if (include_callback) {
- string callback_optional_string = optional_callback ? "?" : "";
if (gen_node_) {
t_struct* exceptions = tfunction->get_xceptions();
string exception_types;
@@ -2647,19 +2720,19 @@
for (vector<t_field*>::const_iterator it = members.begin(); it != members.end(); ++it) {
t_type* t = get_true_type((*it)->get_type());
if (it == members.begin()) {
- exception_types = t->get_name();
+ exception_types = js_type_namespace(t->get_program()) + t->get_name();
} else {
- exception_types += " | " + t->get_name();
+ exception_types += " | " + js_type_namespace(t->get_program()) + t->get_name();
}
}
}
if (exception_types == "") {
- str += "callback" + callback_optional_string + ": (error: void, response: " + ts_get_type(tfunction->get_returntype()) + ")=>void): ";
+ str += "callback?: (error: void, response: " + ts_get_type(tfunction->get_returntype()) + ")=>void): ";
} else {
- str += "callback" + callback_optional_string + ": (error: " + exception_types + ", response: " + ts_get_type(tfunction->get_returntype()) + ")=>void): ";
+ str += "callback?: (error: " + exception_types + ", response: " + ts_get_type(tfunction->get_returntype()) + ")=>void): ";
}
} else {
- str += "callback" + callback_optional_string + ": (data: " + ts_get_type(tfunction->get_returntype()) + ")=>void): ";
+ str += "callback?: (data: " + ts_get_type(tfunction->get_returntype()) + ")=>void): ";
}
if (gen_jquery_) {
diff --git a/compiler/cpp/src/thrift/generate/t_json_generator.cc b/compiler/cpp/src/thrift/generate/t_json_generator.cc
index cd53612..eb4ef79 100644
--- a/compiler/cpp/src/thrift/generate/t_json_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_json_generator.cc
@@ -68,23 +68,23 @@
out_dir_base_ = "gen-json";
}
- virtual ~t_json_generator() {}
+ ~t_json_generator() override = default;
/**
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_program();
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_program() override;
void generate_function(t_function* tfunc);
void generate_field(t_field* field);
- void generate_service(t_service* tservice);
- void generate_struct(t_struct* tstruct);
+ void generate_service(t_service* tservice) override;
+ void generate_struct(t_struct* tstruct) override;
private:
bool should_merge_includes_;
@@ -147,8 +147,8 @@
string t_json_generator::escape_json_string(const string& input) {
std::ostringstream ss;
- for (std::string::const_iterator iter = input.begin(); iter != input.end(); iter++) {
- switch (*iter) {
+ for (char iter : input) {
+ switch (iter) {
case '\\':
ss << "\\\\";
break;
@@ -174,7 +174,7 @@
ss << "\\t";
break;
default:
- ss << *iter;
+ ss << iter;
break;
}
}
@@ -267,8 +267,8 @@
if (ttype->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
- for (map<string, string>::iterator it = ttype->annotations_.begin(); it != ttype->annotations_.end(); ++it) {
- write_key_and_string(it->first, it->second);
+ for (auto & annotation : ttype->annotations_) {
+ write_key_and_string(annotation.first, annotation.second);
}
end_object();
}
@@ -457,8 +457,8 @@
if (ttypedef->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
- for (map<string, string>::iterator it = ttypedef->annotations_.begin(); it != ttypedef->annotations_.end(); ++it) {
- write_key_and_string(it->first, it->second);
+ for (auto & annotation : ttypedef->annotations_) {
+ write_key_and_string(annotation.first, annotation.second);
}
end_object();
}
@@ -564,8 +564,8 @@
if (tenum->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
- for (map<string, string>::iterator it = tenum->annotations_.begin(); it != tenum->annotations_.end(); ++it) {
- write_key_and_string(it->first, it->second);
+ for (auto & annotation : tenum->annotations_) {
+ write_key_and_string(annotation.first, annotation.second);
}
end_object();
}
@@ -603,8 +603,8 @@
if (tstruct->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
- for (map<string, string>::iterator it = tstruct->annotations_.begin(); it != tstruct->annotations_.end(); ++it) {
- write_key_and_string(it->first, it->second);
+ for (auto & annotation : tstruct->annotations_) {
+ write_key_and_string(annotation.first, annotation.second);
}
end_object();
}
@@ -643,8 +643,8 @@
if (tservice->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
- for (map<string, string>::iterator it = tservice->annotations_.begin(); it != tservice->annotations_.end(); ++it) {
- write_key_and_string(it->first, it->second);
+ for (auto & annotation : tservice->annotations_) {
+ write_key_and_string(annotation.first, annotation.second);
}
end_object();
}
@@ -680,8 +680,8 @@
if (tfunc->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
- for (map<string, string>::iterator it = tfunc->annotations_.begin(); it != tfunc->annotations_.end(); ++it) {
- write_key_and_string(it->first, it->second);
+ for (auto & annotation : tfunc->annotations_) {
+ write_key_and_string(annotation.first, annotation.second);
}
end_object();
}
@@ -726,8 +726,8 @@
if (field->annotations_.size() > 0) {
write_key_and("annotations");
start_object();
- for (map<string, string>::iterator it = field->annotations_.begin(); it != field->annotations_.end(); ++it) {
- write_key_and_string(it->first, it->second);
+ for (auto & annotation : field->annotations_) {
+ write_key_and_string(annotation.first, annotation.second);
}
end_object();
}
diff --git a/compiler/cpp/src/thrift/generate/t_lua_generator.cc b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
index adee896..e6432c8 100644
--- a/compiler/cpp/src/thrift/generate/t_lua_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
@@ -56,18 +56,18 @@
/**
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
std::string render_const_value(t_type* type, t_const_value* value);
@@ -149,7 +149,7 @@
std::string type_to_enum(t_type* ttype);
static std::string get_namespace(const t_program* program);
- std::string autogen_comment() {
+ std::string autogen_comment() override {
return std::string("--\n") + "-- Autogenerated by Thrift\n" + "--\n"
+ "-- DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n" + "-- @"
"generated\n"
diff --git a/compiler/cpp/src/thrift/generate/t_netcore_generator.cc b/compiler/cpp/src/thrift/generate/t_netcore_generator.cc
index d2e7da0..1a5c384 100644
--- a/compiler/cpp/src/thrift/generate/t_netcore_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_netcore_generator.cc
@@ -1347,9 +1347,9 @@
indent_up();
out << indent() << "public abstract Task WriteAsync(TProtocol tProtocol, CancellationToken cancellationToken);" << endl
- << indent() << "public readonly bool Isset;" << endl
+ << indent() << "public readonly int Isset;" << endl
<< indent() << "public abstract object Data { get; }" << endl
- << indent() << "protected " << tunion->get_name() << "(bool isset)" << endl
+ << indent() << "protected " << tunion->get_name() << "(int isset)" << endl
<< indent() << "{" << endl;
indent_up();
out << indent() << "Isset = isset;" << endl;
@@ -1361,7 +1361,7 @@
indent_up();
out << indent() << "public override object Data { get { return null; } }" << endl
- << indent() << "public ___undefined() : base(false) {}" << endl << endl;
+ << indent() << "public ___undefined() : base(0) {}" << endl << endl;
out << indent() << "public override Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)" << endl
<< indent() << "{" << endl;
@@ -1390,13 +1390,27 @@
void t_netcore_generator::generate_netcore_union_class(ostream& out, t_struct* tunion, t_field* tfield)
{
+ out << indent() << "public " << type_name(tfield->get_type()) << " As_" << tfield->get_name() << endl;
+ out << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "get" << endl;
+ out << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "return (" << tfield->get_key() << " == Isset) ? (" << type_name(tfield->get_type()) << ")Data : default(" << type_name(tfield->get_type()) << ");" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+ indent_down();
+ out << indent() << "}" << endl
+ << endl;
+
+
out << indent() << "public class " << tfield->get_name() << " : " << tunion->get_name() << endl
<< indent() << "{" << endl;
indent_up();
out << indent() << "private " << type_name(tfield->get_type()) << " _data;" << endl
<< indent() << "public override object Data { get { return _data; } }" << endl
- << indent() << "public " << tfield->get_name() << "(" << type_name(tfield->get_type()) << " data) : base(true)" << endl
+ << indent() << "public " << tfield->get_name() << "(" << type_name(tfield->get_type()) << " data) : base("<< tfield->get_key() <<")" << endl
<< indent() << "{" << endl;
indent_up();
out << indent() << "this._data = data;" << endl;
@@ -2720,7 +2734,7 @@
void t_netcore_generator::prepare_member_name_mapping(void* scope, const vector<t_field*>& members, const string& structname)
{
// begin new scope
- member_mapping_scopes.push_back(member_mapping_scope());
+ member_mapping_scopes.emplace_back();
member_mapping_scope& active = member_mapping_scopes.back();
active.scope_member = scope;
diff --git a/compiler/cpp/src/thrift/generate/t_netcore_generator.h b/compiler/cpp/src/thrift/generate/t_netcore_generator.h
index 6efc922..e98980a 100644
--- a/compiler/cpp/src/thrift/generate/t_netcore_generator.h
+++ b/compiler/cpp/src/thrift/generate/t_netcore_generator.h
@@ -1,3 +1,26 @@
+/*
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
#include <cassert>
#include <string>
diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
new file mode 100644
index 0000000..b76a34d
--- /dev/null
+++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
@@ -0,0 +1,3021 @@
+/*
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+#include <cassert>
+
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <vector>
+#include <cctype>
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sstream>
+
+#include "thrift/platform.h"
+#include "thrift/generate/t_oop_generator.h"
+#include "thrift/generate/t_netstd_generator.h"
+
+using std::map;
+using std::ostream;
+using std::ostringstream;
+using std::string;
+using std::stringstream;
+using std::vector;
+
+//TODO: check for indentation
+//TODO: Do we need seqId_ in generation?
+
+t_netstd_generator::t_netstd_generator(t_program* program, const map<string, string>& parsed_options, const string& option_string)
+ : t_oop_generator(program)
+{
+ (void)option_string;
+
+ union_ = false;
+ serialize_ = false;
+ wcf_ = false;
+ wcf_namespace_.clear();
+
+ map<string, string>::const_iterator iter;
+
+ for (iter = parsed_options.begin(); iter != parsed_options.end(); ++iter)
+ {
+ if (iter->first.compare("union") == 0)
+ {
+ union_ = true;
+ }
+ else if (iter->first.compare("serial") == 0)
+ {
+ serialize_ = true;
+ wcf_namespace_ = iter->second; // since there can be only one namespace
+ }
+ else if (iter->first.compare("wcf") == 0)
+ {
+ wcf_ = true;
+ wcf_namespace_ = iter->second;
+ }
+ else
+ {
+ throw "unknown option netstd:" + iter->first;
+ }
+ }
+
+ out_dir_base_ = "gen-netstd";
+}
+
+static string correct_function_name_for_async(string const& function_name)
+{
+ string const async_end = "Async";
+ size_t i = function_name.find(async_end);
+ if (i != string::npos)
+ {
+ return function_name + async_end;
+ }
+
+ return function_name;
+}
+
+/**
+* \brief Search and replace "_args" substring in struct name if exist (for C# class naming)
+* \param struct_name
+* \return Modified struct name ("Struct_args" -> "StructArgs") or original name
+*/
+static string check_and_correct_struct_name(const string& struct_name)
+{
+ string args_end = "_args";
+ size_t i = struct_name.find(args_end);
+ if (i != string::npos)
+ {
+ string new_struct_name = struct_name;
+ new_struct_name.replace(i, args_end.length(), "Args");
+ return new_struct_name;
+ }
+
+ string result_end = "_result";
+ size_t j = struct_name.find(result_end);
+ if (j != string::npos)
+ {
+ string new_struct_name = struct_name;
+ new_struct_name.replace(j, result_end.length(), "Result");
+ return new_struct_name;
+ }
+
+ return struct_name;
+}
+
+static bool field_has_default(t_field* tfield) { return tfield->get_value() != NULL; }
+
+static bool field_is_required(t_field* tfield) { return tfield->get_req() == t_field::T_REQUIRED; }
+
+static bool type_can_be_null(t_type* ttype)
+{
+ while (ttype->is_typedef())
+ {
+ ttype = static_cast<t_typedef*>(ttype)->get_type();
+ }
+
+ return ttype->is_container() || ttype->is_struct() || ttype->is_xception() || ttype->is_string();
+}
+
+bool t_netstd_generator::is_wcf_enabled() const { return wcf_; }
+
+bool t_netstd_generator::is_serialize_enabled() const { return serialize_; }
+
+bool t_netstd_generator::is_union_enabled() const { return union_; }
+
+map<string, int> t_netstd_generator::get_keywords_list() const
+{
+ return netstd_keywords;
+}
+
+void t_netstd_generator::init_generator()
+{
+ MKDIR(get_out_dir().c_str());
+
+ // for usage of csharp namespaces in thrift files (from files for csharp)
+ namespace_name_ = program_->get_namespace("netstd");
+ if (namespace_name_.empty())
+ {
+ namespace_name_ = program_->get_namespace("netstd");
+ }
+
+ string dir = namespace_name_;
+ string subdir = get_out_dir().c_str();
+ string::size_type loc;
+
+ while ((loc = dir.find(".")) != string::npos)
+ {
+ subdir = subdir + "/" + dir.substr(0, loc);
+ MKDIR(subdir.c_str());
+ dir = dir.substr(loc + 1);
+ }
+ if (dir.size() > 0)
+ {
+ subdir = subdir + "/" + dir;
+ MKDIR(subdir.c_str());
+ }
+
+ namespace_dir_ = subdir;
+ init_keywords();
+
+ while (!member_mapping_scopes.empty())
+ {
+ cleanup_member_name_mapping(member_mapping_scopes.back().scope_member);
+ }
+
+ pverbose(".NET Standard options:\n");
+ pverbose("- union ...... %s\n", (is_union_enabled() ? "ON" : "off"));
+ pverbose("- serialize .. %s\n", (is_serialize_enabled() ? "ON" : "off"));
+ pverbose("- wcf ........ %s\n", (is_wcf_enabled() ? "ON" : "off"));
+}
+
+string t_netstd_generator::normalize_name(string name)
+{
+ string tmp(name);
+ transform(tmp.begin(), tmp.end(), tmp.begin(), static_cast<int(*)(int)>(tolower));
+
+ // un-conflict keywords by prefixing with "@"
+ if (netstd_keywords.find(tmp) != netstd_keywords.end())
+ {
+ return "@" + name;
+ }
+
+ // no changes necessary
+ return name;
+}
+
+void t_netstd_generator::init_keywords()
+{
+ netstd_keywords.clear();
+
+ // C# keywords
+ netstd_keywords["abstract"] = 1;
+ netstd_keywords["as"] = 1;
+ netstd_keywords["base"] = 1;
+ netstd_keywords["bool"] = 1;
+ netstd_keywords["break"] = 1;
+ netstd_keywords["byte"] = 1;
+ netstd_keywords["case"] = 1;
+ netstd_keywords["catch"] = 1;
+ netstd_keywords["char"] = 1;
+ netstd_keywords["checked"] = 1;
+ netstd_keywords["class"] = 1;
+ netstd_keywords["const"] = 1;
+ netstd_keywords["continue"] = 1;
+ netstd_keywords["decimal"] = 1;
+ netstd_keywords["default"] = 1;
+ netstd_keywords["delegate"] = 1;
+ netstd_keywords["do"] = 1;
+ netstd_keywords["double"] = 1;
+ netstd_keywords["else"] = 1;
+ netstd_keywords["enum"] = 1;
+ netstd_keywords["event"] = 1;
+ netstd_keywords["explicit"] = 1;
+ netstd_keywords["extern"] = 1;
+ netstd_keywords["false"] = 1;
+ netstd_keywords["finally"] = 1;
+ netstd_keywords["fixed"] = 1;
+ netstd_keywords["float"] = 1;
+ netstd_keywords["for"] = 1;
+ netstd_keywords["foreach"] = 1;
+ netstd_keywords["goto"] = 1;
+ netstd_keywords["if"] = 1;
+ netstd_keywords["implicit"] = 1;
+ netstd_keywords["in"] = 1;
+ netstd_keywords["int"] = 1;
+ netstd_keywords["interface"] = 1;
+ netstd_keywords["internal"] = 1;
+ netstd_keywords["is"] = 1;
+ netstd_keywords["lock"] = 1;
+ netstd_keywords["long"] = 1;
+ netstd_keywords["namespace"] = 1;
+ netstd_keywords["new"] = 1;
+ netstd_keywords["null"] = 1;
+ netstd_keywords["object"] = 1;
+ netstd_keywords["operator"] = 1;
+ netstd_keywords["out"] = 1;
+ netstd_keywords["override"] = 1;
+ netstd_keywords["params"] = 1;
+ netstd_keywords["private"] = 1;
+ netstd_keywords["protected"] = 1;
+ netstd_keywords["public"] = 1;
+ netstd_keywords["readonly"] = 1;
+ netstd_keywords["ref"] = 1;
+ netstd_keywords["return"] = 1;
+ netstd_keywords["sbyte"] = 1;
+ netstd_keywords["sealed"] = 1;
+ netstd_keywords["short"] = 1;
+ netstd_keywords["sizeof"] = 1;
+ netstd_keywords["stackalloc"] = 1;
+ netstd_keywords["static"] = 1;
+ netstd_keywords["string"] = 1;
+ netstd_keywords["struct"] = 1;
+ netstd_keywords["switch"] = 1;
+ netstd_keywords["this"] = 1;
+ netstd_keywords["throw"] = 1;
+ netstd_keywords["true"] = 1;
+ netstd_keywords["try"] = 1;
+ netstd_keywords["typeof"] = 1;
+ netstd_keywords["uint"] = 1;
+ netstd_keywords["ulong"] = 1;
+ netstd_keywords["unchecked"] = 1;
+ netstd_keywords["unsafe"] = 1;
+ netstd_keywords["ushort"] = 1;
+ netstd_keywords["using"] = 1;
+ netstd_keywords["virtual"] = 1;
+ netstd_keywords["void"] = 1;
+ netstd_keywords["volatile"] = 1;
+ netstd_keywords["while"] = 1;
+
+ // C# contextual keywords
+ netstd_keywords["add"] = 1;
+ netstd_keywords["alias"] = 1;
+ netstd_keywords["ascending"] = 1;
+ netstd_keywords["async"] = 1;
+ netstd_keywords["await"] = 1;
+ netstd_keywords["descending"] = 1;
+ netstd_keywords["dynamic"] = 1;
+ netstd_keywords["from"] = 1;
+ netstd_keywords["get"] = 1;
+ netstd_keywords["global"] = 1;
+ netstd_keywords["group"] = 1;
+ netstd_keywords["into"] = 1;
+ netstd_keywords["join"] = 1;
+ netstd_keywords["let"] = 1;
+ netstd_keywords["orderby"] = 1;
+ netstd_keywords["partial"] = 1;
+ netstd_keywords["remove"] = 1;
+ netstd_keywords["select"] = 1;
+ netstd_keywords["set"] = 1;
+ netstd_keywords["value"] = 1;
+ netstd_keywords["var"] = 1;
+ netstd_keywords["where"] = 1;
+ netstd_keywords["yield"] = 1;
+
+ netstd_keywords["when"] = 1;
+}
+
+void t_netstd_generator::start_netstd_namespace(ostream& out)
+{
+ if (!namespace_name_.empty())
+ {
+ out << "namespace " << namespace_name_ << endl;
+ scope_up(out);
+ }
+}
+
+void t_netstd_generator::end_netstd_namespace(ostream& out)
+{
+ if (!namespace_name_.empty())
+ {
+ scope_down(out);
+ }
+}
+
+string t_netstd_generator::netstd_type_usings() const
+{
+ string namespaces =
+ "using System;\n"
+ "using System.Collections;\n"
+ "using System.Collections.Generic;\n"
+ "using System.Text;\n"
+ "using System.IO;\n"
+ "using System.Threading;\n"
+ "using System.Threading.Tasks;\n"
+ "using Thrift;\n"
+ "using Thrift.Collections;\n";
+
+ if (is_wcf_enabled())
+ {
+ namespaces += "using System.ServiceModel;\n";
+ namespaces += "using System.Runtime.Serialization;\n";
+ }
+
+ return namespaces + endl;
+}
+
+string t_netstd_generator::netstd_thrift_usings() const
+{
+ string namespaces =
+ "using Thrift.Protocol;\n"
+ "using Thrift.Protocol.Entities;\n"
+ "using Thrift.Protocol.Utilities;\n"
+ "using Thrift.Transport;\n"
+ "using Thrift.Transport.Client;\n"
+ "using Thrift.Transport.Server;\n"
+ "using Thrift.Processor;\n";
+
+ return namespaces + endl;
+}
+
+void t_netstd_generator::close_generator()
+{
+}
+
+void t_netstd_generator::generate_typedef(t_typedef* ttypedef)
+{
+ (void)ttypedef;
+}
+
+void t_netstd_generator::generate_enum(t_enum* tenum)
+{
+ int ic = indent_count();
+ string f_enum_name = namespace_dir_ + "/" + tenum->get_name() + ".cs";
+
+ ofstream_with_content_based_conditional_update f_enum;
+ f_enum.open(f_enum_name.c_str());
+
+ generate_enum(f_enum, tenum);
+
+ f_enum.close();
+ indent_validate(ic, "generate_enum");
+}
+
+void t_netstd_generator::generate_enum(ostream& out, t_enum* tenum)
+{
+ out << autogen_comment() << endl;
+
+ start_netstd_namespace(out);
+ generate_netstd_doc(out, tenum);
+
+ out << indent() << "public enum " << tenum->get_name() << endl;
+ scope_up(out);
+
+ vector<t_enum_value*> constants = tenum->get_constants();
+ vector<t_enum_value*>::iterator c_iter;
+
+ for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter)
+ {
+ generate_netstd_doc(out, *c_iter);
+ int value = (*c_iter)->get_value();
+ out << indent() << (*c_iter)->get_name() << " = " << value << "," << endl;
+ }
+
+ scope_down(out);
+ end_netstd_namespace(out);
+}
+
+void t_netstd_generator::generate_consts(vector<t_const*> consts)
+{
+ if (consts.empty())
+ {
+ return;
+ }
+
+ string f_consts_name = namespace_dir_ + '/' + program_name_ + ".Constants.cs";
+ ofstream_with_content_based_conditional_update f_consts;
+ f_consts.open(f_consts_name.c_str());
+
+ generate_consts(f_consts, consts);
+
+ f_consts.close();
+}
+
+void t_netstd_generator::generate_consts(ostream& out, vector<t_const*> consts)
+{
+ if (consts.empty())
+ {
+ return;
+ }
+
+ out << autogen_comment() << netstd_type_usings() << endl;
+
+ start_netstd_namespace(out);
+
+ out << indent() << "public static class " << make_valid_csharp_identifier(program_name_) << "Constants" << endl;
+
+ scope_up(out);
+
+ vector<t_const*>::iterator c_iter;
+ bool need_static_constructor = false;
+ for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter)
+ {
+ generate_netstd_doc(out, *c_iter);
+ if (print_const_value(out, (*c_iter)->get_name(), (*c_iter)->get_type(), (*c_iter)->get_value(), false))
+ {
+ need_static_constructor = true;
+ }
+ }
+
+ if (need_static_constructor)
+ {
+ print_const_constructor(out, consts);
+ }
+
+ scope_down(out);
+ end_netstd_namespace(out);
+}
+
+void t_netstd_generator::print_const_def_value(ostream& out, string name, t_type* type, t_const_value* value)
+{
+ if (type->is_struct() || type->is_xception())
+ {
+ const vector<t_field*>& fields = static_cast<t_struct*>(type)->get_members();
+ const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
+ vector<t_field*>::const_iterator f_iter;
+ map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
+ prepare_member_name_mapping(static_cast<t_struct*>(type));
+
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter)
+ {
+ t_field* field = NULL;
+
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ if ((*f_iter)->get_name() == v_iter->first->get_string())
+ {
+ field = *f_iter;
+ }
+ }
+
+ if (field == NULL)
+ {
+ throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
+ }
+
+ t_type* field_type = field->get_type();
+
+ string val = render_const_value(out, name, field_type, v_iter->second);
+ out << indent() << name << "." << prop_name(field) << " = " << val << ";" << endl;
+ }
+
+ cleanup_member_name_mapping(static_cast<t_struct*>(type));
+ }
+ else if (type->is_map())
+ {
+ t_type* ktype = static_cast<t_map*>(type)->get_key_type();
+ t_type* vtype = static_cast<t_map*>(type)->get_val_type();
+ const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
+ map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter)
+ {
+ string key = render_const_value(out, name, ktype, v_iter->first);
+ string val = render_const_value(out, name, vtype, v_iter->second);
+ out << indent() << name << "[" << key << "]" << " = " << val << ";" << endl;
+ }
+ }
+ else if (type->is_list() || type->is_set())
+ {
+ t_type* etype;
+ if (type->is_list())
+ {
+ etype = static_cast<t_list*>(type)->get_elem_type();
+ }
+ else
+ {
+ etype = static_cast<t_set*>(type)->get_elem_type();
+ }
+
+ const vector<t_const_value*>& val = value->get_list();
+ vector<t_const_value*>::const_iterator v_iter;
+ for (v_iter = val.begin(); v_iter != val.end(); ++v_iter)
+ {
+ string val = render_const_value(out, name, etype, *v_iter);
+ out << indent() << name << ".Add(" << val << ");" << endl;
+ }
+ }
+}
+
+void t_netstd_generator::print_const_constructor(ostream& out, vector<t_const*> consts)
+{
+ out << indent() << "static " << make_valid_csharp_identifier(program_name_).c_str() << "Constants()" << endl;
+ scope_up(out);
+
+ vector<t_const*>::iterator c_iter;
+ for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter)
+ {
+ string name = (*c_iter)->get_name();
+ t_type* type = (*c_iter)->get_type();
+ t_const_value* value = (*c_iter)->get_value();
+
+ print_const_def_value(out, name, type, value);
+ }
+ scope_down(out);
+}
+
+bool t_netstd_generator::print_const_value(ostream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval, bool needtype)
+{
+ out << indent();
+ bool need_static_construction = !in_static;
+ while (type->is_typedef())
+ {
+ type = static_cast<t_typedef*>(type)->get_type();
+ }
+
+ if (!defval || needtype)
+ {
+ out << (in_static ? "" : type->is_base_type() ? "public const " : "public static ") << type_name(type) << " ";
+ }
+
+ if (type->is_base_type())
+ {
+ string v2 = render_const_value(out, name, type, value);
+ out << normalize_name(name) << " = " << v2 << ";" << endl;
+ need_static_construction = false;
+ }
+ else if (type->is_enum())
+ {
+ out << name << " = " << type_name(type) << "." << value->get_identifier_name() << ";" << endl;
+ need_static_construction = false;
+ }
+ else if (type->is_struct() || type->is_xception())
+ {
+ out << name << " = new " << type_name(type) << "();" << endl;
+ }
+ else if (type->is_map())
+ {
+ out << name << " = new " << type_name(type) << "();" << endl;
+ }
+ else if (type->is_list() || type->is_set())
+ {
+ out << name << " = new " << type_name(type) << "();" << endl;
+ }
+
+ if (defval && !type->is_base_type() && !type->is_enum())
+ {
+ print_const_def_value(out, name, type, value);
+ }
+
+ return need_static_construction;
+}
+
+string t_netstd_generator::render_const_value(ostream& out, string name, t_type* type, t_const_value* value)
+{
+ (void)name;
+ ostringstream render;
+
+ if (type->is_base_type())
+ {
+ t_base_type::t_base tbase = static_cast<t_base_type*>(type)->get_base();
+ switch (tbase)
+ {
+ case t_base_type::TYPE_STRING:
+ render << '"' << get_escaped_string(value) << '"';
+ break;
+ case t_base_type::TYPE_BOOL:
+ render << ((value->get_integer() > 0) ? "true" : "false");
+ break;
+ case t_base_type::TYPE_I8:
+ case t_base_type::TYPE_I16:
+ case t_base_type::TYPE_I32:
+ case t_base_type::TYPE_I64:
+ render << value->get_integer();
+ break;
+ case t_base_type::TYPE_DOUBLE:
+ if (value->get_type() == t_const_value::CV_INTEGER)
+ {
+ render << value->get_integer();
+ }
+ else
+ {
+ render << value->get_double();
+ }
+ break;
+ default:
+ throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
+ }
+ }
+ else if (type->is_enum())
+ {
+ render << type->get_name() << "." << value->get_identifier_name();
+ }
+ else
+ {
+ string t = tmp("tmp");
+ print_const_value(out, t, type, value, true, true, true);
+ render << t;
+ }
+
+ return render.str();
+}
+
+void t_netstd_generator::generate_struct(t_struct* tstruct)
+{
+ if (is_union_enabled() && tstruct->is_union())
+ {
+ generate_netstd_union(tstruct);
+ }
+ else
+ {
+ generate_netstd_struct(tstruct, false);
+ }
+}
+
+void t_netstd_generator::generate_xception(t_struct* txception)
+{
+ generate_netstd_struct(txception, true);
+}
+
+void t_netstd_generator::generate_netstd_struct(t_struct* tstruct, bool is_exception)
+{
+ int ic = indent_count();
+
+ string f_struct_name = namespace_dir_ + "/" + (tstruct->get_name()) + ".cs";
+ ofstream_with_content_based_conditional_update f_struct;
+
+ f_struct.open(f_struct_name.c_str());
+
+ f_struct << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << endl;
+
+ generate_netstd_struct_definition(f_struct, tstruct, is_exception);
+
+ f_struct.close();
+
+ indent_validate(ic, "generate_netstd_struct");
+}
+
+void t_netstd_generator::generate_netstd_struct_definition(ostream& out, t_struct* tstruct, bool is_exception, bool in_class, bool is_result)
+{
+ if (!in_class)
+ {
+ start_netstd_namespace(out);
+ }
+
+ out << endl;
+
+ generate_netstd_doc(out, tstruct);
+ prepare_member_name_mapping(tstruct);
+
+ if ((is_serialize_enabled() || is_wcf_enabled()) && !is_exception)
+ {
+ out << indent() << "[DataContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
+ }
+
+ bool is_final = tstruct->annotations_.find("final") != tstruct->annotations_.end();
+
+ string sharp_struct_name = check_and_correct_struct_name(normalize_name(tstruct->get_name()));
+
+ out << indent() << "public " << (is_final ? "sealed " : "") << "partial class " << sharp_struct_name << " : ";
+
+ if (is_exception)
+ {
+ out << "TException, ";
+ }
+
+ out << "TBase" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ const vector<t_field*>& members = tstruct->get_members();
+ vector<t_field*>::const_iterator m_iter;
+
+ // make private members with public Properties
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter)
+ {
+ // if the field is required, then we use auto-properties
+ if (!field_is_required((*m_iter)))
+ {
+ out << indent() << "private " << declare_field(*m_iter, false, "_") << endl;
+ }
+ }
+ out << endl;
+
+ bool has_non_required_fields = false;
+ bool has_required_fields = false;
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter)
+ {
+ generate_netstd_doc(out, *m_iter);
+ generate_property(out, *m_iter, true, true);
+ bool is_required = field_is_required((*m_iter));
+ if (is_required)
+ {
+ has_required_fields = true;
+ }
+ else
+ {
+ has_non_required_fields = true;
+ }
+ }
+
+ bool generate_isset = has_non_required_fields;
+ if (generate_isset)
+ {
+ out << endl;
+ if (is_serialize_enabled() || is_wcf_enabled())
+ {
+ out << indent() << "[DataMember(Order = 1)]" << endl;
+ }
+ out << indent() << "public Isset __isset;" << endl;
+ if (is_serialize_enabled() || is_wcf_enabled())
+ {
+ out << indent() << "[DataContract]" << endl;
+ }
+
+ out << indent() << "public struct Isset" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter)
+ {
+ bool is_required = field_is_required((*m_iter));
+ // if it is required, don't need Isset for that variable
+ // if it is not required, if it has a default value, we need to generate Isset
+ if (!is_required)
+ {
+ if (is_serialize_enabled() || is_wcf_enabled())
+ {
+ out << indent() << "[DataMember]" << endl;
+ }
+ out << indent() << "public bool " << normalize_name((*m_iter)->get_name()) << ";" << endl;
+ }
+ }
+
+ indent_down();
+ out << indent() << "}" << endl << endl;
+
+ if (generate_isset && (is_serialize_enabled() || is_wcf_enabled()))
+ {
+ out << indent() << "#region XmlSerializer support" << endl << endl;
+
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter)
+ {
+ bool is_required = field_is_required(*m_iter);
+ // if it is required, don't need Isset for that variable
+ // if it is not required, if it has a default value, we need to generate Isset
+ if (!is_required)
+ {
+ out << indent() << "public bool ShouldSerialize" << prop_name(*m_iter) << "()" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "return __isset." << normalize_name((*m_iter)->get_name()) << ";" << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl;
+ }
+ }
+
+ out << indent() << "#endregion XmlSerializer support" << endl << endl;
+ }
+ }
+
+ // We always want a default, no argument constructor for Reading
+ out << indent() << "public " << sharp_struct_name << "()" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter)
+ {
+ t_type* t = (*m_iter)->get_type();
+ while (t->is_typedef())
+ {
+ t = static_cast<t_typedef*>(t)->get_type();
+ }
+ if ((*m_iter)->get_value() != NULL)
+ {
+ if (field_is_required((*m_iter)))
+ {
+ print_const_value(out, "this." + prop_name(*m_iter), t, (*m_iter)->get_value(), true, true);
+ }
+ else
+ {
+ print_const_value(out, "this._" + (*m_iter)->get_name(), t, (*m_iter)->get_value(), true, true);
+ // Optionals with defaults are marked set
+ out << indent() << "this.__isset." << normalize_name((*m_iter)->get_name()) << " = true;" << endl;
+ }
+ }
+ }
+ indent_down();
+ out << indent() << "}" << endl << endl;
+
+ if (has_required_fields)
+ {
+ out << indent() << "public " << sharp_struct_name << "(";
+ bool first = true;
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter)
+ {
+ if (field_is_required(*m_iter))
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ out << ", ";
+ }
+ out << type_name((*m_iter)->get_type()) << " " << (*m_iter)->get_name();
+ }
+ }
+ out << ") : this()" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter)
+ {
+ if (field_is_required(*m_iter))
+ {
+ out << indent() << "this." << prop_name(*m_iter) << " = " << (*m_iter)->get_name() << ";" << endl;
+ }
+ }
+
+ indent_down();
+ out << indent() << "}" << endl << endl;
+ }
+
+ generate_netstd_struct_reader(out, tstruct);
+ if (is_result)
+ {
+ generate_netstd_struct_result_writer(out, tstruct);
+ }
+ else
+ {
+ generate_netstd_struct_writer(out, tstruct);
+ }
+ generate_netstd_struct_equals(out, tstruct);
+ generate_netstd_struct_hashcode(out, tstruct);
+ generate_netstd_struct_tostring(out, tstruct);
+
+ indent_down();
+ out << indent() << "}" << endl << endl;
+
+ // generate a corresponding WCF fault to wrap the exception
+ if ((is_serialize_enabled() || is_wcf_enabled()) && is_exception)
+ {
+ generate_netstd_wcffault(out, tstruct);
+ }
+
+ cleanup_member_name_mapping(tstruct);
+ if (!in_class)
+ {
+ end_netstd_namespace(out);
+ }
+}
+
+void t_netstd_generator::generate_netstd_wcffault(ostream& out, t_struct* tstruct)
+{
+ out << endl;
+ out << indent() << "[DataContract]" << endl;
+
+ bool is_final = tstruct->annotations_.find("final") != tstruct->annotations_.end();
+
+ out << indent() << "public " << (is_final ? "sealed " : "") << "partial class " << tstruct->get_name() << "Fault" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ const vector<t_field*>& members = tstruct->get_members();
+ vector<t_field*>::const_iterator m_iter;
+
+ // make private members with public Properties
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter)
+ {
+ // if the field is required, then we use auto-properties
+ if (!field_is_required((*m_iter)))
+ {
+ out << indent() << "private " << declare_field(*m_iter, false, "_") << endl;
+ }
+ }
+ out << endl;
+
+ for (m_iter = members.begin(); m_iter != members.end(); ++m_iter)
+ {
+ generate_property(out, *m_iter, true, false);
+ }
+
+ indent_down();
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_netstd_struct_reader(ostream& out, t_struct* tstruct)
+{
+ out << indent() << "public async Task ReadAsync(TProtocol iprot, CancellationToken cancellationToken)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "iprot.IncrementRecursionDepth();" << endl
+ << indent() << "try" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ const vector<t_field*>& fields = tstruct->get_members();
+ vector<t_field*>::const_iterator f_iter;
+
+ // Required variables aren't in __isset, so we need tmp vars to check them
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ if (field_is_required(*f_iter))
+ {
+ out << indent() << "bool isset_" << (*f_iter)->get_name() << " = false;" << endl;
+ }
+ }
+
+ out << indent() << "TField field;" << endl
+ << indent() << "await iprot.ReadStructBeginAsync(cancellationToken);" << endl
+ << indent() << "while (true)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "field = await iprot.ReadFieldBeginAsync(cancellationToken);" << endl
+ << indent() << "if (field.Type == TType.Stop)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "break;" << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl
+ << indent() << "switch (field.ID)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ bool is_required = field_is_required(*f_iter);
+ out << indent() << "case " << (*f_iter)->get_key() << ":" << endl;
+ indent_up();
+ out << indent() << "if (field.Type == " << type_to_enum((*f_iter)->get_type()) << ")" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ generate_deserialize_field(out, *f_iter);
+ if (is_required)
+ {
+ out << indent() << "isset_" << (*f_iter)->get_name() << " = true;" << endl;
+ }
+
+ indent_down();
+ out << indent() << "}" << endl
+ << indent() << "else" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);" << endl;
+ indent_down();
+ out << indent() << "}" << endl
+ << indent() << "break;" << endl;
+ indent_down();
+ }
+
+ out << indent() << "default: " << endl;
+ indent_up();
+ out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);" << endl
+ << indent() << "break;" << endl;
+ indent_down();
+ indent_down();
+ out << indent() << "}" << endl
+ << endl
+ << indent() << "await iprot.ReadFieldEndAsync(cancellationToken);" << endl;
+ indent_down();
+ out << indent() << "}" << endl
+ << endl
+ << indent() << "await iprot.ReadStructEndAsync(cancellationToken);" << endl;
+
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ if (field_is_required((*f_iter)))
+ {
+ out << indent() << "if (!isset_" << (*f_iter)->get_name() << ")" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "throw new TProtocolException(TProtocolException.INVALID_DATA);" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+ }
+ }
+
+ indent_down();
+ out << indent() << "}" << endl;
+ out << indent() << "finally" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "iprot.DecrementRecursionDepth();" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_netstd_struct_writer(ostream& out, t_struct* tstruct)
+{
+ out << indent() << "public async Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ out << indent() << "oprot.IncrementRecursionDepth();" << endl
+ << indent() << "try" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ string name = tstruct->get_name();
+ const vector<t_field*>& fields = tstruct->get_sorted_members();
+ vector<t_field*>::const_iterator f_iter;
+
+ out << indent() << "var struc = new TStruct(\"" << name << "\");" << endl
+ << indent() << "await oprot.WriteStructBeginAsync(struc, cancellationToken);" << endl;
+
+ if (fields.size() > 0)
+ {
+ out << indent() << "var field = new TField();" << endl;
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ bool is_required = field_is_required(*f_iter);
+ if (!is_required)
+ {
+ bool null_allowed = type_can_be_null((*f_iter)->get_type());
+ if (null_allowed)
+ {
+ out << indent() << "if (" << prop_name(*f_iter) << " != null && __isset." << normalize_name((*f_iter)->get_name()) << ")" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ }
+ else
+ {
+ out << indent() << "if (__isset." << normalize_name((*f_iter)->get_name()) << ")" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ }
+ }
+ out << indent() << "field.Name = \"" << (*f_iter)->get_name() << "\";" << endl
+ << indent() << "field.Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl
+ << indent() << "field.ID = " << (*f_iter)->get_key() << ";" << endl
+ << indent() << "await oprot.WriteFieldBeginAsync(field, cancellationToken);" << endl;
+
+ generate_serialize_field(out, *f_iter);
+
+ out << indent() << "await oprot.WriteFieldEndAsync(cancellationToken);" << endl;
+ if (!is_required)
+ {
+ indent_down();
+ out << indent() << "}" << endl;
+ }
+ }
+ }
+
+ out << indent() << "await oprot.WriteFieldStopAsync(cancellationToken);" << endl
+ << indent() << "await oprot.WriteStructEndAsync(cancellationToken);" << endl;
+ indent_down();
+ out << indent() << "}" << endl
+ << indent() << "finally" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "oprot.DecrementRecursionDepth();" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_netstd_struct_result_writer(ostream& out, t_struct* tstruct)
+{
+ out << indent() << "public async Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ out << indent() << "oprot.IncrementRecursionDepth();" << endl
+ << indent() << "try" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ string name = tstruct->get_name();
+ const vector<t_field*>& fields = tstruct->get_sorted_members();
+ vector<t_field*>::const_iterator f_iter;
+
+ out << indent() << "var struc = new TStruct(\"" << name << "\");" << endl
+ << indent() << "await oprot.WriteStructBeginAsync(struc, cancellationToken);" << endl;
+
+ if (fields.size() > 0)
+ {
+ out << indent() << "var field = new TField();" << endl;
+ bool first = true;
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ if (first)
+ {
+ first = false;
+ out << endl << indent() << "if";
+ }
+ else
+ {
+ out << indent() << "else if";
+ }
+
+ out << "(this.__isset." << normalize_name((*f_iter)->get_name()) << ")" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ bool null_allowed = type_can_be_null((*f_iter)->get_type());
+ if (null_allowed)
+ {
+ out << indent() << "if (" << prop_name(*f_iter) << " != null)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ }
+
+ out << indent() << "field.Name = \"" << prop_name(*f_iter) << "\";" << endl
+ << indent() << "field.Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl
+ << indent() << "field.ID = " << (*f_iter)->get_key() << ";" << endl
+ << indent() << "await oprot.WriteFieldBeginAsync(field, cancellationToken);" << endl;
+
+ generate_serialize_field(out, *f_iter);
+
+ out << indent() << "await oprot.WriteFieldEndAsync(cancellationToken);" << endl;
+
+ if (null_allowed)
+ {
+ indent_down();
+ out << indent() << "}" << endl;
+ }
+
+ indent_down();
+ out << indent() << "}" << endl;
+ }
+ }
+
+ out << indent() << "await oprot.WriteFieldStopAsync(cancellationToken);" << endl
+ << indent() << "await oprot.WriteStructEndAsync(cancellationToken);" << endl;
+ indent_down();
+ out << indent() << "}" << endl
+ << indent() << "finally" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "oprot.DecrementRecursionDepth();" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_netstd_struct_tostring(ostream& out, t_struct* tstruct)
+{
+ out << indent() << "public override string ToString()" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "var sb = new StringBuilder(\"" << tstruct->get_name() << "(\");" << endl;
+
+ const vector<t_field*>& fields = tstruct->get_members();
+ vector<t_field*>::const_iterator f_iter;
+
+ bool useFirstFlag = false;
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ if (!field_is_required((*f_iter)))
+ {
+ out << indent() << "bool __first = true;" << endl;
+ useFirstFlag = true;
+ }
+ break;
+ }
+
+ bool had_required = false; // set to true after first required field has been processed
+
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ bool is_required = field_is_required((*f_iter));
+ if (!is_required)
+ {
+ bool null_allowed = type_can_be_null((*f_iter)->get_type());
+ if (null_allowed)
+ {
+ out << indent() << "if (" << prop_name((*f_iter)) << " != null && __isset." << normalize_name((*f_iter)->get_name()) << ")" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ }
+ else
+ {
+ out << indent() << "if (__isset." << normalize_name((*f_iter)->get_name()) << ")" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ }
+ }
+
+ if (useFirstFlag && (!had_required))
+ {
+ out << indent() << "if(!__first) { sb.Append(\", \"); }" << endl;
+ if (!is_required)
+ {
+ out << indent() << "__first = false;" << endl;
+ }
+ out << indent() << "sb.Append(\"" << prop_name(*f_iter) << ": \");" << endl;
+ }
+ else
+ {
+ out << indent() << "sb.Append(\", " << prop_name(*f_iter) << ": \");" << endl;
+ }
+
+ t_type* ttype = (*f_iter)->get_type();
+ if (ttype->is_xception() || ttype->is_struct())
+ {
+ out << indent() << "sb.Append(" << prop_name(*f_iter) << "== null ? \"<null>\" : " << prop_name(*f_iter) << ".ToString());" << endl;
+ }
+ else
+ {
+ out << indent() << "sb.Append(" << prop_name(*f_iter) << ");" << endl;
+ }
+
+ if (!is_required)
+ {
+ indent_down();
+ out << indent() << "}" << endl;
+ }
+ else
+ {
+ had_required = true; // now __first must be false, so we don't need to check it anymore
+ }
+ }
+
+ out << indent() << "sb.Append(\")\");" << endl
+ << indent() << "return sb.ToString();" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+}
+
+void t_netstd_generator::generate_netstd_union(t_struct* tunion)
+{
+ int ic = indent_count();
+
+ string f_union_name = namespace_dir_ + "/" + (tunion->get_name()) + ".cs";
+ ofstream_with_content_based_conditional_update f_union;
+
+ f_union.open(f_union_name.c_str());
+
+ f_union << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << endl;
+
+ generate_netstd_union_definition(f_union, tunion);
+
+ f_union.close();
+
+ indent_validate(ic, "generate_netstd_union.");
+}
+
+void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct* tunion)
+{
+ // Let's define the class first
+ start_netstd_namespace(out);
+
+ out << indent() << "public abstract partial class " << tunion->get_name() << " : TUnionBase" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ out << indent() << "public abstract Task WriteAsync(TProtocol tProtocol, CancellationToken cancellationToken);" << endl
+ << indent() << "public readonly int Isset;" << endl
+ << indent() << "public abstract object Data { get; }" << endl
+ << indent() << "protected " << tunion->get_name() << "(int isset)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "Isset = isset;" << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl;
+
+ out << indent() << "public class ___undefined : " << tunion->get_name() << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ out << indent() << "public override object Data { get { return null; } }" << endl
+ << indent() << "public ___undefined() : base(0) {}" << endl << endl;
+
+ out << indent() << "public override Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "throw new TProtocolException( TProtocolException.INVALID_DATA, \"Cannot persist an union type which is not set.\");" << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl;
+
+ const vector<t_field*>& fields = tunion->get_members();
+ vector<t_field*>::const_iterator f_iter;
+
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ generate_netstd_union_class(out, tunion, (*f_iter));
+ }
+
+ generate_netstd_union_reader(out, tunion);
+
+ indent_down();
+ out << indent() << "}" << endl << endl;
+
+ end_netstd_namespace(out);
+}
+
+void t_netstd_generator::generate_netstd_union_class(ostream& out, t_struct* tunion, t_field* tfield)
+{
+ out << indent() << "public " << type_name(tfield->get_type()) << " As_" << tfield->get_name() << endl;
+ out << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "get" << endl;
+ out << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "return (" << tfield->get_key() << " == Isset) ? (" << type_name(tfield->get_type()) << ")Data : default(" << type_name(tfield->get_type()) << ");" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+ indent_down();
+ out << indent() << "}" << endl
+ << endl;
+
+
+ out << indent() << "public class " << tfield->get_name() << " : " << tunion->get_name() << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ out << indent() << "private " << type_name(tfield->get_type()) << " _data;" << endl
+ << indent() << "public override object Data { get { return _data; } }" << endl
+ << indent() << "public " << tfield->get_name() << "(" << type_name(tfield->get_type()) << " data) : base("<< tfield->get_key() <<")" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "this._data = data;" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+
+ out << indent() << "public override async Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {" << endl;
+ indent_up();
+
+ out << indent() << "oprot.IncrementRecursionDepth();" << endl
+ << indent() << "try" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ out << indent() << "var struc = new TStruct(\"" << tunion->get_name() << "\");" << endl
+ << indent() << "await oprot.WriteStructBeginAsync(struc, cancellationToken);" << endl;
+
+ out << indent() << "var field = new TField();" << endl
+ << indent() << "field.Name = \"" << tfield->get_name() << "\";" << endl
+ << indent() << "field.Type = " << type_to_enum(tfield->get_type()) << ";" << endl
+ << indent() << "field.ID = " << tfield->get_key() << ";" << endl
+ << indent() << "await oprot.WriteFieldBeginAsync(field, cancellationToken);" << endl;
+
+ generate_serialize_field(out, tfield, "_data", true);
+
+ out << indent() << "await oprot.WriteFieldEndAsync(cancellationToken);" << endl
+ << indent() << "await oprot.WriteFieldStopAsync(cancellationToken);" << endl
+ << indent() << "await oprot.WriteStructEndAsync(cancellationToken);" << endl;
+ indent_down();
+ out << indent() << "}" << endl
+ << indent() << "finally" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "oprot.DecrementRecursionDepth();" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+ out << indent() << "}" << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_netstd_struct_equals(ostream& out, t_struct* tstruct)
+{
+ out << indent() << "public override bool Equals(object that)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "var other = that as " << check_and_correct_struct_name(normalize_name(tstruct->get_name())) << ";" << endl
+ << indent() << "if (other == null) return false;" << endl
+ << indent() << "if (ReferenceEquals(this, other)) return true;" << endl;
+
+ const vector<t_field*>& fields = tstruct->get_members();
+ vector<t_field*>::const_iterator f_iter;
+
+ bool first = true;
+
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ if (first)
+ {
+ first = false;
+ out << indent() << "return ";
+ indent_up();
+ }
+ else
+ {
+ out << endl;
+ out << indent() << "&& ";
+ }
+ if (!field_is_required((*f_iter)))
+ {
+ out << "((__isset." << normalize_name((*f_iter)->get_name()) << " == other.__isset."
+ << normalize_name((*f_iter)->get_name()) << ") && ((!__isset."
+ << normalize_name((*f_iter)->get_name()) << ") || (";
+ }
+ t_type* ttype = (*f_iter)->get_type();
+ if (ttype->is_container() || ttype->is_binary())
+ {
+ out << "TCollections.Equals(";
+ }
+ else
+ {
+ out << "System.Object.Equals(";
+ }
+ out << prop_name((*f_iter)) << ", other." << prop_name((*f_iter)) << ")";
+ if (!field_is_required((*f_iter)))
+ {
+ out << ")))";
+ }
+ }
+ if (first)
+ {
+ out << indent() << "return true;" << endl;
+ }
+ else
+ {
+ out << ";" << endl;
+ indent_down();
+ }
+
+ indent_down();
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_netstd_struct_hashcode(ostream& out, t_struct* tstruct)
+{
+ out << indent() << "public override int GetHashCode() {" << endl;
+ indent_up();
+
+ out << indent() << "int hashcode = 0;" << endl;
+ out << indent() << "unchecked {" << endl;
+ indent_up();
+
+ const vector<t_field*>& fields = tstruct->get_members();
+ vector<t_field*>::const_iterator f_iter;
+
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ t_type* ttype = (*f_iter)->get_type();
+ out << indent() << "hashcode = (hashcode * 397) ^ ";
+ if (field_is_required((*f_iter)))
+ {
+ out << "(";
+ }
+ else
+ {
+ out << "(!__isset." << normalize_name((*f_iter)->get_name()) << " ? 0 : ";
+ }
+ if (ttype->is_container())
+ {
+ out << "(TCollections.GetHashCode(" << prop_name((*f_iter)) << "))";
+ }
+ else
+ {
+ out << "(" << prop_name((*f_iter)) << ".GetHashCode())";
+ }
+ out << ");" << endl;
+ }
+
+ indent_down();
+ out << indent() << "}" << endl;
+ out << indent() << "return hashcode;" << endl;
+
+ indent_down();
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_service(t_service* tservice)
+{
+ int ic = indent_count();
+
+ string f_service_name = namespace_dir_ + "/" + service_name_ + ".cs";
+ ofstream_with_content_based_conditional_update f_service;
+ f_service.open(f_service_name.c_str());
+
+ f_service << autogen_comment() << netstd_type_usings() << netstd_thrift_usings() << endl;
+
+ start_netstd_namespace(f_service);
+
+ f_service << indent() << "public partial class " << normalize_name(service_name_) << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ generate_service_interface(f_service, tservice);
+ generate_service_client(f_service, tservice);
+ generate_service_server(f_service, tservice);
+ generate_service_helpers(f_service, tservice);
+
+ indent_down();
+ f_service << indent() << "}" << endl;
+
+ end_netstd_namespace(f_service);
+ f_service.close();
+
+ indent_validate(ic, "generate_service.");
+}
+
+void t_netstd_generator::generate_service_interface(ostream& out, t_service* tservice)
+{
+ string extends = "";
+ string extends_iface = "";
+ if (tservice->get_extends() != NULL)
+ {
+ extends = type_name(tservice->get_extends());
+ extends_iface = " : " + extends + ".IAsync";
+ }
+
+ //out << endl << endl;
+
+ generate_netstd_doc(out, tservice);
+
+ if (is_wcf_enabled())
+ {
+ out << indent() << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
+ }
+
+ out << indent() << "public interface IAsync" << extends_iface << endl
+ << indent() << "{" << endl;
+
+ indent_up();
+ vector<t_function*> functions = tservice->get_functions();
+ vector<t_function*>::iterator f_iter;
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter)
+ {
+ generate_netstd_doc(out, *f_iter);
+
+ // if we're using WCF, add the corresponding attributes
+ if (is_wcf_enabled())
+ {
+ out << indent() << "[OperationContract]" << endl;
+
+ const vector<t_field*>& xceptions = (*f_iter)->get_xceptions()->get_members();
+ vector<t_field*>::const_iterator x_iter;
+ for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter)
+ {
+ out << indent() << "[FaultContract(typeof(" + type_name((*x_iter)->get_type()) + "Fault))]" << endl;
+ }
+ }
+
+ out << indent() << function_signature_async(*f_iter) << ";" << endl << endl;
+ }
+ indent_down();
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_service_helpers(ostream& out, t_service* tservice)
+{
+ vector<t_function*> functions = tservice->get_functions();
+ vector<t_function*>::iterator f_iter;
+
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter)
+ {
+ t_struct* ts = (*f_iter)->get_arglist();
+ generate_netstd_struct_definition(out, ts, false, true);
+ generate_function_helpers(out, *f_iter);
+ }
+}
+
+void t_netstd_generator::generate_service_client(ostream& out, t_service* tservice)
+{
+ string extends = "";
+ string extends_client = "";
+ if (tservice->get_extends() != NULL)
+ {
+ extends = type_name(tservice->get_extends());
+ extends_client = extends + ".Client, ";
+ }
+ else
+ {
+ extends_client = "TBaseClient, IDisposable, ";
+ }
+
+ out << endl;
+
+ generate_netstd_doc(out, tservice);
+
+ out << indent() << "public class Client : " << extends_client << "IAsync" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ out << indent() << "public Client(TProtocol protocol) : this(protocol, protocol)" << endl
+ << indent() << "{" << endl
+ << indent() << "}" << endl
+ << endl
+ << indent() << "public Client(TProtocol inputProtocol, TProtocol outputProtocol) : base(inputProtocol, outputProtocol)"
+ << indent() << "{" << endl
+ << indent() << "}" << endl;
+
+ vector<t_function*> functions = tservice->get_functions();
+ vector<t_function*>::const_iterator functions_iterator;
+
+ for (functions_iterator = functions.begin(); functions_iterator != functions.end(); ++functions_iterator)
+ {
+ string function_name = correct_function_name_for_async((*functions_iterator)->get_name());
+
+ // async
+ out << indent() << "public async " << function_signature_async(*functions_iterator, "") << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ string argsname = (*functions_iterator)->get_name() + "Args";
+
+ out << indent() << "await OutputProtocol.WriteMessageBeginAsync(new TMessage(\"" << function_name
+ << "\", " << ((*functions_iterator)->is_oneway() ? "TMessageType.Oneway" : "TMessageType.Call") << ", SeqId), cancellationToken);" << endl
+ << indent() << endl
+ << indent() << "var args = new " << argsname << "();" << endl;
+
+ t_struct* arg_struct = (*functions_iterator)->get_arglist();
+ prepare_member_name_mapping(arg_struct);
+ const vector<t_field*>& fields = arg_struct->get_members();
+ vector<t_field*>::const_iterator fld_iter;
+
+ for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter)
+ {
+ out << indent() << "args." << prop_name(*fld_iter) << " = " << normalize_name((*fld_iter)->get_name()) << ";" << endl;
+ }
+
+ out << indent() << endl
+ << indent() << "await args.WriteAsync(OutputProtocol, cancellationToken);" << endl
+ << indent() << "await OutputProtocol.WriteMessageEndAsync(cancellationToken);" << endl
+ << indent() << "await OutputProtocol.Transport.FlushAsync(cancellationToken);" << endl;
+
+ if (!(*functions_iterator)->is_oneway())
+ {
+ string resultname = (*functions_iterator)->get_name() + "Result";
+ t_struct noargs(program_);
+ t_struct* xs = (*functions_iterator)->get_xceptions();
+ prepare_member_name_mapping(xs, xs->get_members(), resultname);
+
+ out << indent() << endl
+ << indent() << "var msg = await InputProtocol.ReadMessageBeginAsync(cancellationToken);" << endl
+ << indent() << "if (msg.Type == TMessageType.Exception)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ out << indent() << "var x = await TApplicationException.ReadAsync(InputProtocol, cancellationToken);" << endl
+ << indent() << "await InputProtocol.ReadMessageEndAsync(cancellationToken);" << endl
+ << indent() << "throw x;" << endl;
+ indent_down();
+
+ out << indent() << "}" << endl
+ << endl
+ << indent() << "var result = new " << resultname << "();" << endl
+ << indent() << "await result.ReadAsync(InputProtocol, cancellationToken);" << endl
+ << indent() << "await InputProtocol.ReadMessageEndAsync(cancellationToken);" << endl;
+
+ if (!(*functions_iterator)->get_returntype()->is_void())
+ {
+ out << indent() << "if (result.__isset.success)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "return result.Success;" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+ }
+
+ const vector<t_field*>& xceptions = xs->get_members();
+ vector<t_field*>::const_iterator x_iter;
+ for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter)
+ {
+ out << indent() << "if (result.__isset." << normalize_name((*x_iter)->get_name()) << ")" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "throw result." << prop_name(*x_iter) << ";" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+ }
+
+ if ((*functions_iterator)->get_returntype()->is_void())
+ {
+ out << indent() << "return;" << endl;
+ }
+ else
+ {
+ out << indent() << "throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, \""
+ << function_name << " failed: unknown result\");" << endl;
+ }
+
+ cleanup_member_name_mapping((*functions_iterator)->get_xceptions());
+ indent_down();
+ out << indent() << "}" << endl << endl;
+ }
+ else
+ {
+ indent_down();
+ out << indent() << "}" << endl;
+ }
+ }
+
+ indent_down();
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_service_server(ostream& out, t_service* tservice)
+{
+ vector<t_function*> functions = tservice->get_functions();
+ vector<t_function*>::iterator f_iter;
+
+ string extends = "";
+ string extends_processor = "";
+ if (tservice->get_extends() != NULL)
+ {
+ extends = type_name(tservice->get_extends());
+ extends_processor = extends + ".AsyncProcessor, ";
+ }
+
+ out << indent() << "public class AsyncProcessor : " << extends_processor << "ITAsyncProcessor" << endl
+ << indent() << "{" << endl;
+
+ indent_up();
+
+ out << indent() << "private IAsync _iAsync;" << endl
+ << endl
+ << indent() << "public AsyncProcessor(IAsync iAsync)";
+
+ if (!extends.empty())
+ {
+ out << " : base(iAsync)";
+ }
+
+ out << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ out << indent() << "if (iAsync == null) throw new ArgumentNullException(nameof(iAsync));" << endl
+ << endl
+ << indent() << "_iAsync = iAsync;" << endl;
+
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter)
+ {
+ string function_name = (*f_iter)->get_name();
+ out << indent() << "processMap_[\"" << correct_function_name_for_async(function_name) << "\"] = " << function_name << "_ProcessAsync;" << endl;
+ }
+
+ indent_down();
+ out << indent() << "}" << endl
+ << endl;
+
+ if (extends.empty())
+ {
+ out << indent() << "protected delegate Task ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot, CancellationToken cancellationToken);" << endl;
+ }
+
+ if (extends.empty())
+ {
+ out << indent() << "protected Dictionary<string, ProcessFunction> processMap_ = new Dictionary<string, ProcessFunction>();" << endl;
+ }
+
+ out << endl;
+
+ if (extends.empty())
+ {
+ out << indent() << "public async Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "return await ProcessAsync(iprot, oprot, CancellationToken.None);" << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl;
+
+ out << indent() << "public async Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken cancellationToken)" << endl;
+ }
+ else
+ {
+ out << indent() << "public new async Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "return await ProcessAsync(iprot, oprot, CancellationToken.None);" << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl;
+
+ out << indent() << "public new async Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken cancellationToken)" << endl;
+ }
+
+ out << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "try" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "var msg = await iprot.ReadMessageBeginAsync(cancellationToken);" << endl
+ << endl
+ << indent() << "ProcessFunction fn;" << endl
+ << indent() << "processMap_.TryGetValue(msg.Name, out fn);" << endl
+ << endl
+ << indent() << "if (fn == null)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "await TProtocolUtil.SkipAsync(iprot, TType.Struct, cancellationToken);" << endl
+ << indent() << "await iprot.ReadMessageEndAsync(cancellationToken);" << endl
+ << indent() << "var x = new TApplicationException (TApplicationException.ExceptionType.UnknownMethod, \"Invalid method name: '\" + msg.Name + \"'\");" << endl
+ << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID), cancellationToken);" << endl
+ << indent() << "await x.WriteAsync(oprot, cancellationToken);" << endl
+ << indent() << "await oprot.WriteMessageEndAsync(cancellationToken);" << endl
+ << indent() << "await oprot.Transport.FlushAsync(cancellationToken);" << endl
+ << indent() << "return true;" << endl;
+ indent_down();
+ out << indent() << "}" << endl
+ << endl
+ << indent() << "await fn(msg.SeqID, iprot, oprot, cancellationToken);" << endl
+ << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+ out << indent() << "catch (IOException)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ out << indent() << "return false;" << endl;
+ indent_down();
+ out << indent() << "}" << endl
+ << endl
+ << indent() << "return true;" << endl;
+ indent_down();
+ out << indent() << "}" << endl << endl;
+
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter)
+ {
+ generate_process_function_async(out, tservice, *f_iter);
+ }
+
+ indent_down();
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_function_helpers(ostream& out, t_function* tfunction)
+{
+ if (tfunction->is_oneway())
+ {
+ return;
+ }
+
+ t_struct result(program_, tfunction->get_name() + "_result");
+ t_field success(tfunction->get_returntype(), "success", 0);
+ if (!tfunction->get_returntype()->is_void())
+ {
+ result.append(&success);
+ }
+
+ t_struct* xs = tfunction->get_xceptions();
+ const vector<t_field*>& fields = xs->get_members();
+ vector<t_field*>::const_iterator f_iter;
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ result.append(*f_iter);
+ }
+
+ generate_netstd_struct_definition(out, &result, false, true, true);
+}
+
+void t_netstd_generator::generate_process_function_async(ostream& out, t_service* tservice, t_function* tfunction)
+{
+ (void)tservice;
+ out << indent() << "public async Task " << tfunction->get_name()
+ << "_ProcessAsync(int seqid, TProtocol iprot, TProtocol oprot, CancellationToken cancellationToken)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ string argsname = tfunction->get_name() + "Args";
+ string resultname = tfunction->get_name() + "Result";
+
+ out << indent() << "var args = new " << argsname << "();" << endl
+ << indent() << "await args.ReadAsync(iprot, cancellationToken);" << endl
+ << indent() << "await iprot.ReadMessageEndAsync(cancellationToken);" << endl;
+
+ if (!tfunction->is_oneway())
+ {
+ out << indent() << "var result = new " << resultname << "();" << endl;
+ }
+
+ out << indent() << "try" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ t_struct* xs = tfunction->get_xceptions();
+ const vector<t_field*>& xceptions = xs->get_members();
+
+ if (xceptions.size() > 0)
+ {
+ out << indent() << "try" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ }
+
+ t_struct* arg_struct = tfunction->get_arglist();
+ const vector<t_field*>& fields = arg_struct->get_members();
+ vector<t_field*>::const_iterator f_iter;
+
+ out << indent();
+ if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void())
+ {
+ out << "result.Success = ";
+ }
+
+ out << "await _iAsync." << normalize_name(tfunction->get_name()) << "Async(";
+
+ bool first = true;
+ prepare_member_name_mapping(arg_struct);
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ out << ", ";
+ }
+
+ out << "args." << prop_name(*f_iter);
+ }
+
+ cleanup_member_name_mapping(arg_struct);
+
+ if (!first)
+ {
+ out << ", ";
+ }
+
+ out << "cancellationToken);" << endl;
+
+ vector<t_field*>::const_iterator x_iter;
+
+ prepare_member_name_mapping(xs, xs->get_members(), resultname);
+ if (xceptions.size() > 0)
+ {
+ indent_down();
+ out << indent() << "}" << endl;
+
+ for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter)
+ {
+ out << indent() << "catch (" << type_name((*x_iter)->get_type()) << " " << (*x_iter)->get_name() << ")" << endl
+ << indent() << "{" << endl;
+
+ if (!tfunction->is_oneway())
+ {
+ indent_up();
+ out << indent() << "result." << prop_name(*x_iter) << " = " << (*x_iter)->get_name() << ";" << endl;
+ indent_down();
+ }
+ out << indent() << "}" << endl;
+ }
+ }
+
+ if (!tfunction->is_oneway())
+ {
+ out << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(\""
+ << correct_function_name_for_async(tfunction->get_name()) << "\", TMessageType.Reply, seqid), cancellationToken); " << endl
+ << indent() << "await result.WriteAsync(oprot, cancellationToken);" << endl;
+ }
+ indent_down();
+
+ cleanup_member_name_mapping(xs);
+
+ out << indent() << "}" << endl
+ << indent() << "catch (TTransportException)" << endl
+ << indent() << "{" << endl
+ << indent() << " throw;" << endl
+ << indent() << "}" << endl
+ << indent() << "catch (Exception ex)" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ out << indent() << "Console.Error.WriteLine(\"Error occurred in processor:\");" << endl
+ << indent() << "Console.Error.WriteLine(ex.ToString());" << endl;
+
+ if (tfunction->is_oneway())
+ {
+ indent_down();
+ out << indent() << "}" << endl;
+ }
+ else
+ {
+ out << indent() << "var x = new TApplicationException(TApplicationException.ExceptionType.InternalError,\" Internal error.\");" << endl
+ << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(\"" << correct_function_name_for_async(tfunction->get_name())
+ << "\", TMessageType.Exception, seqid), cancellationToken);" << endl
+ << indent() << "await x.WriteAsync(oprot, cancellationToken);" << endl;
+ indent_down();
+
+ out << indent() << "}" << endl
+ << indent() << "await oprot.WriteMessageEndAsync(cancellationToken);" << endl
+ << indent() << "await oprot.Transport.FlushAsync(cancellationToken);" << endl;
+ }
+
+ indent_down();
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_netstd_union_reader(ostream& out, t_struct* tunion)
+{
+ // Thanks to THRIFT-1768, we don't need to check for required fields in the union
+ const vector<t_field*>& fields = tunion->get_members();
+ vector<t_field*>::const_iterator f_iter;
+
+ out << indent() << "public static async Task<" << tunion->get_name() << "> ReadAsync(TProtocol iprot, CancellationToken cancellationToken)" << endl;
+ scope_up(out);
+
+ out << indent() << "iprot.IncrementRecursionDepth();" << endl;
+ out << indent() << "try" << endl;
+ scope_up(out);
+
+ out << indent() << tunion->get_name() << " retval;" << endl;
+ out << indent() << "await iprot.ReadStructBeginAsync(cancellationToken);" << endl;
+ out << indent() << "TField field = await iprot.ReadFieldBeginAsync(cancellationToken);" << endl;
+ // we cannot have the first field be a stop -- we must have a single field defined
+ out << indent() << "if (field.Type == TType.Stop)" << endl;
+ scope_up(out);
+ out << indent() << "await iprot.ReadFieldEndAsync(cancellationToken);" << endl;
+ out << indent() << "retval = new ___undefined();" << endl;
+ scope_down(out);
+ out << indent() << "else" << endl;
+ scope_up(out);
+ out << indent() << "switch (field.ID)" << endl;
+ scope_up(out);
+
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ out << indent() << "case " << (*f_iter)->get_key() << ":" << endl;
+ indent_up();
+ out << indent() << "if (field.Type == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl;
+ indent_up();
+
+ out << indent() << type_name((*f_iter)->get_type()) << " temp;" << endl;
+ generate_deserialize_field(out, (*f_iter), "temp", true);
+ out << indent() << "retval = new " << (*f_iter)->get_name() << "(temp);" << endl;
+
+ indent_down();
+ out << indent() << "} else { " << endl << indent() << " await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);"
+ << endl << indent() << " retval = new ___undefined();" << endl << indent() << "}" << endl
+ << indent() << "break;" << endl;
+ indent_down();
+ }
+
+ out << indent() << "default: " << endl;
+ indent_up();
+ out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);" << endl << indent()
+ << "retval = new ___undefined();" << endl;
+ out << indent() << "break;" << endl;
+ indent_down();
+
+ scope_down(out);
+
+ out << indent() << "await iprot.ReadFieldEndAsync(cancellationToken);" << endl;
+
+ out << indent() << "if ((await iprot.ReadFieldBeginAsync(cancellationToken)).Type != TType.Stop)" << endl;
+ scope_up(out);
+ out << indent() << "throw new TProtocolException(TProtocolException.INVALID_DATA);" << endl;
+ scope_down(out);
+
+ // end of else for TStop
+ scope_down(out);
+ out << indent() << "await iprot.ReadStructEndAsync(cancellationToken);" << endl;
+ out << indent() << "return retval;" << endl;
+ indent_down();
+
+ scope_down(out);
+ out << indent() << "finally" << endl;
+ scope_up(out);
+ out << indent() << "iprot.DecrementRecursionDepth();" << endl;
+ scope_down(out);
+
+ out << indent() << "}" << endl << endl;
+}
+
+void t_netstd_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix, bool is_propertyless)
+{
+ t_type* type = tfield->get_type();
+ while (type->is_typedef())
+ {
+ type = static_cast<t_typedef*>(type)->get_type();
+ }
+
+ if (type->is_void())
+ {
+ throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " + prefix + tfield->get_name();
+ }
+
+ string name = prefix + (is_propertyless ? "" : prop_name(tfield));
+
+ if (type->is_struct() || type->is_xception())
+ {
+ generate_deserialize_struct(out, static_cast<t_struct*>(type), name);
+ }
+ else if (type->is_container())
+ {
+ generate_deserialize_container(out, type, name);
+ }
+ else if (type->is_base_type() || type->is_enum())
+ {
+ out << indent() << name << " = ";
+
+ if (type->is_enum())
+ {
+ out << "(" << type_name(type) << ")";
+ }
+
+ out << "await iprot.";
+
+ if (type->is_base_type())
+ {
+ t_base_type::t_base tbase = static_cast<t_base_type*>(type)->get_base();
+ switch (tbase)
+ {
+ case t_base_type::TYPE_VOID:
+ throw "compiler error: cannot serialize void field in a struct: " + name;
+ break;
+ case t_base_type::TYPE_STRING:
+ if (type->is_binary())
+ {
+ out << "ReadBinaryAsync(cancellationToken);";
+ }
+ else
+ {
+ out << "ReadStringAsync(cancellationToken);";
+ }
+ break;
+ case t_base_type::TYPE_BOOL:
+ out << "ReadBoolAsync(cancellationToken);";
+ break;
+ case t_base_type::TYPE_I8:
+ out << "ReadByteAsync(cancellationToken);";
+ break;
+ case t_base_type::TYPE_I16:
+ out << "ReadI16Async(cancellationToken);";
+ break;
+ case t_base_type::TYPE_I32:
+ out << "ReadI32Async(cancellationToken);";
+ break;
+ case t_base_type::TYPE_I64:
+ out << "ReadI64Async(cancellationToken);";
+ break;
+ case t_base_type::TYPE_DOUBLE:
+ out << "ReadDoubleAsync(cancellationToken);";
+ break;
+ default:
+ throw "compiler error: no C# name for base type " + t_base_type::t_base_name(tbase);
+ }
+ }
+ else if (type->is_enum())
+ {
+ out << "ReadI32Async(cancellationToken);";
+ }
+ out << endl;
+ }
+ else
+ {
+ printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n", tfield->get_name().c_str(), type_name(type).c_str());
+ }
+}
+
+void t_netstd_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix)
+{
+ if (is_union_enabled() && tstruct->is_union())
+ {
+ out << indent() << prefix << " = await " << type_name(tstruct) << ".ReadAsync(iprot, cancellationToken);" << endl;
+ }
+ else
+ {
+ out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl
+ << indent() << "await " << prefix << ".ReadAsync(iprot, cancellationToken);" << endl;
+ }
+}
+
+void t_netstd_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix)
+{
+ out << indent() << "{" << endl;
+ indent_up();
+
+ string obj;
+
+ if (ttype->is_map())
+ {
+ obj = tmp("_map");
+ }
+ else if (ttype->is_set())
+ {
+ obj = tmp("_set");
+ }
+ else if (ttype->is_list())
+ {
+ obj = tmp("_list");
+ }
+
+ out << indent() << prefix << " = new " << type_name(ttype) << "();" << endl;
+ if (ttype->is_map())
+ {
+ out << indent() << "TMap " << obj << " = await iprot.ReadMapBeginAsync(cancellationToken);" << endl;
+ }
+ else if (ttype->is_set())
+ {
+ out << indent() << "TSet " << obj << " = await iprot.ReadSetBeginAsync(cancellationToken);" << endl;
+ }
+ else if (ttype->is_list())
+ {
+ out << indent() << "TList " << obj << " = await iprot.ReadListBeginAsync(cancellationToken);" << endl;
+ }
+
+ string i = tmp("_i");
+ out << indent() << "for(int " << i << " = 0; " << i << " < " << obj << ".Count; ++" << i << ")" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ if (ttype->is_map())
+ {
+ generate_deserialize_map_element(out, static_cast<t_map*>(ttype), prefix);
+ }
+ else if (ttype->is_set())
+ {
+ generate_deserialize_set_element(out, static_cast<t_set*>(ttype), prefix);
+ }
+ else if (ttype->is_list())
+ {
+ generate_deserialize_list_element(out, static_cast<t_list*>(ttype), prefix);
+ }
+
+ indent_down();
+ out << indent() << "}" << endl;
+
+ if (ttype->is_map())
+ {
+ out << indent() << "await iprot.ReadMapEndAsync(cancellationToken);" << endl;
+ }
+ else if (ttype->is_set())
+ {
+ out << indent() << "await iprot.ReadSetEndAsync(cancellationToken);" << endl;
+ }
+ else if (ttype->is_list())
+ {
+ out << indent() << "await iprot.ReadListEndAsync(cancellationToken);" << endl;
+ }
+
+ indent_down();
+ out << indent() << "}" << endl;
+}
+
+void t_netstd_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix)
+{
+ string key = tmp("_key");
+ string val = tmp("_val");
+
+ t_field fkey(tmap->get_key_type(), key);
+ t_field fval(tmap->get_val_type(), val);
+
+ out << indent() << declare_field(&fkey) << endl;
+ out << indent() << declare_field(&fval) << endl;
+
+ generate_deserialize_field(out, &fkey);
+ generate_deserialize_field(out, &fval);
+
+ out << indent() << prefix << "[" << key << "] = " << val << ";" << endl;
+}
+
+void t_netstd_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix)
+{
+ string elem = tmp("_elem");
+ t_field felem(tset->get_elem_type(), elem);
+
+ out << indent() << declare_field(&felem) << endl;
+
+ generate_deserialize_field(out, &felem);
+
+ out << indent() << prefix << ".Add(" << elem << ");" << endl;
+}
+
+void t_netstd_generator::generate_deserialize_list_element(ostream& out, t_list* tlist, string prefix)
+{
+ string elem = tmp("_elem");
+ t_field felem(tlist->get_elem_type(), elem);
+
+ out << indent() << declare_field(&felem) << endl;
+
+ generate_deserialize_field(out, &felem);
+
+ out << indent() << prefix << ".Add(" << elem << ");" << endl;
+}
+
+void t_netstd_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix, bool is_propertyless)
+{
+ t_type* type = tfield->get_type();
+ while (type->is_typedef())
+ {
+ type = static_cast<t_typedef*>(type)->get_type();
+ }
+
+ string name = prefix + (is_propertyless ? "" : prop_name(tfield));
+
+ if (type->is_void())
+ {
+ throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE: " + name;
+ }
+
+ if (type->is_struct() || type->is_xception())
+ {
+ generate_serialize_struct(out, static_cast<t_struct*>(type), name);
+ }
+ else if (type->is_container())
+ {
+ generate_serialize_container(out, type, name);
+ }
+ else if (type->is_base_type() || type->is_enum())
+ {
+ out << indent() << "await oprot.";
+
+ string nullable_name = name;
+
+ if (type->is_base_type())
+ {
+ t_base_type::t_base tbase = static_cast<t_base_type*>(type)->get_base();
+ switch (tbase)
+ {
+ case t_base_type::TYPE_VOID:
+ throw "compiler error: cannot serialize void field in a struct: " + name;
+ case t_base_type::TYPE_STRING:
+ if (type->is_binary())
+ {
+ out << "WriteBinaryAsync(";
+ }
+ else
+ {
+ out << "WriteStringAsync(";
+ }
+ out << name << ", cancellationToken);";
+ break;
+ case t_base_type::TYPE_BOOL:
+ out << "WriteBoolAsync(" << nullable_name << ", cancellationToken);";
+ break;
+ case t_base_type::TYPE_I8:
+ out << "WriteByteAsync(" << nullable_name << ", cancellationToken);";
+ break;
+ case t_base_type::TYPE_I16:
+ out << "WriteI16Async(" << nullable_name << ", cancellationToken);";
+ break;
+ case t_base_type::TYPE_I32:
+ out << "WriteI32Async(" << nullable_name << ", cancellationToken);";
+ break;
+ case t_base_type::TYPE_I64:
+ out << "WriteI64Async(" << nullable_name << ", cancellationToken);";
+ break;
+ case t_base_type::TYPE_DOUBLE:
+ out << "WriteDoubleAsync(" << nullable_name << ", cancellationToken);";
+ break;
+ default:
+ throw "compiler error: no C# name for base type " + t_base_type::t_base_name(tbase);
+ }
+ }
+ else if (type->is_enum())
+ {
+ out << "WriteI32Async((int)" << nullable_name << ", cancellationToken);";
+ }
+ out << endl;
+ }
+ else
+ {
+ printf("DO NOT KNOW HOW TO SERIALIZE '%s%s' TYPE '%s'\n", prefix.c_str(), tfield->get_name().c_str(), type_name(type).c_str());
+ }
+}
+
+void t_netstd_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix)
+{
+ (void)tstruct;
+ out << indent() << "await " << prefix << ".WriteAsync(oprot, cancellationToken);" << endl;
+}
+
+void t_netstd_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix)
+{
+ out << indent() << "{" << endl;
+ indent_up();
+
+ if (ttype->is_map())
+ {
+ out << indent() << "await oprot.WriteMapBeginAsync(new TMap(" << type_to_enum(static_cast<t_map*>(ttype)->get_key_type())
+ << ", " << type_to_enum(static_cast<t_map*>(ttype)->get_val_type()) << ", " << prefix
+ << ".Count), cancellationToken);" << endl;
+ }
+ else if (ttype->is_set())
+ {
+ out << indent() << "await oprot.WriteSetBeginAsync(new TSet(" << type_to_enum(static_cast<t_set*>(ttype)->get_elem_type())
+ << ", " << prefix << ".Count), cancellationToken);" << endl;
+ }
+ else if (ttype->is_list())
+ {
+ out << indent() << "await oprot.WriteListBeginAsync(new TList("
+ << type_to_enum(static_cast<t_list*>(ttype)->get_elem_type()) << ", " << prefix << ".Count), cancellationToken);"
+ << endl;
+ }
+
+ string iter = tmp("_iter");
+ if (ttype->is_map())
+ {
+ out << indent() << "foreach (" << type_name(static_cast<t_map*>(ttype)->get_key_type()) << " " << iter
+ << " in " << prefix << ".Keys)";
+ }
+ else if (ttype->is_set())
+ {
+ out << indent() << "foreach (" << type_name(static_cast<t_set*>(ttype)->get_elem_type()) << " " << iter
+ << " in " << prefix << ")";
+ }
+ else if (ttype->is_list())
+ {
+ out << indent() << "foreach (" << type_name(static_cast<t_list*>(ttype)->get_elem_type()) << " " << iter
+ << " in " << prefix << ")";
+ }
+
+ out << endl;
+ out << indent() << "{" << endl;
+ indent_up();
+
+ if (ttype->is_map())
+ {
+ generate_serialize_map_element(out, static_cast<t_map*>(ttype), iter, prefix);
+ }
+ else if (ttype->is_set())
+ {
+ generate_serialize_set_element(out, static_cast<t_set*>(ttype), iter);
+ }
+ else if (ttype->is_list())
+ {
+ generate_serialize_list_element(out, static_cast<t_list*>(ttype), iter);
+ }
+
+ indent_down();
+ out << indent() << "}" << endl;
+
+ if (ttype->is_map())
+ {
+ out << indent() << "await oprot.WriteMapEndAsync(cancellationToken);" << endl;
+ }
+ else if (ttype->is_set())
+ {
+ out << indent() << "await oprot.WriteSetEndAsync(cancellationToken);" << endl;
+ }
+ else if (ttype->is_list())
+ {
+ out << indent() << "await oprot.WriteListEndAsync(cancellationToken);" << endl;
+ }
+
+ indent_down();
+ out << indent() << "}" << endl;
+}
+
+void t_netstd_generator::generate_serialize_map_element(ostream& out, t_map* tmap, string iter, string map)
+{
+ t_field kfield(tmap->get_key_type(), iter);
+ generate_serialize_field(out, &kfield, "");
+ t_field vfield(tmap->get_val_type(), map + "[" + iter + "]");
+ generate_serialize_field(out, &vfield, "");
+}
+
+void t_netstd_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter)
+{
+ t_field efield(tset->get_elem_type(), iter);
+ generate_serialize_field(out, &efield, "");
+}
+
+void t_netstd_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter)
+{
+ t_field efield(tlist->get_elem_type(), iter);
+ generate_serialize_field(out, &efield, "");
+}
+
+void t_netstd_generator::generate_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset)
+{
+ generate_netstd_property(out, tfield, isPublic, generateIsset, "_");
+}
+
+void t_netstd_generator::generate_netstd_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset, string fieldPrefix)
+{
+ if ((is_serialize_enabled() || is_wcf_enabled()) && isPublic)
+ {
+ out << indent() << "[DataMember(Order = 0)]" << endl;
+ }
+ bool is_required = field_is_required(tfield);
+ if (is_required)
+ {
+ out << indent() << (isPublic ? "public " : "private ") << type_name(tfield->get_type()) << " " << prop_name(tfield) << " { get; set; }" << endl;
+ }
+ else
+ {
+ out << indent() << (isPublic ? "public " : "private ") << type_name(tfield->get_type()) << " " << prop_name(tfield) << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ out << indent() << "get" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ bool use_nullable = false;
+
+ out << indent() << "return " << fieldPrefix + tfield->get_name() << ";" << endl;
+ indent_down();
+ out << indent() << "}" << endl
+ << indent() << "set" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ if (use_nullable)
+ {
+ if (generateIsset)
+ {
+ out << indent() << "__isset." << normalize_name(tfield->get_name()) << " = value.HasValue;" << endl;
+ }
+ out << indent() << "if (value.HasValue) this." << fieldPrefix + tfield->get_name() << " = value.Value;" << endl;
+ }
+ else
+ {
+ if (generateIsset)
+ {
+ out << indent() << "__isset." << normalize_name(tfield->get_name()) << " = true;" << endl;
+ }
+ out << indent() << "this." << fieldPrefix + tfield->get_name() << " = value;" << endl;
+ }
+
+ indent_down();
+ out << indent() << "}" << endl;
+ indent_down();
+ out << indent() << "}" << endl;
+ }
+ out << endl;
+}
+
+string t_netstd_generator::make_valid_csharp_identifier(string const& fromName)
+{
+ string str = fromName;
+ if (str.empty())
+ {
+ return str;
+ }
+
+ // tests rely on this
+ assert(('A' < 'Z') && ('a' < 'z') && ('0' < '9'));
+
+ // if the first letter is a number, we add an additional underscore in front of it
+ char c = str.at(0);
+ if (('0' <= c) && (c <= '9'))
+ {
+ str = "_" + str;
+ }
+
+ // following chars: letter, number or underscore
+ for (size_t i = 0; i < str.size(); ++i)
+ {
+ c = str.at(i);
+ if (('A' > c || c > 'Z') && ('a' > c || c > 'z') && ('0' > c || c > '9') && '_' != c)
+ {
+ str.replace(i, 1, "_");
+ }
+ }
+
+ return str;
+}
+
+void t_netstd_generator::cleanup_member_name_mapping(void* scope)
+{
+ if (member_mapping_scopes.empty())
+ {
+ throw "internal error: cleanup_member_name_mapping() no scope active";
+ }
+
+ member_mapping_scope& active = member_mapping_scopes.back();
+ if (active.scope_member != scope)
+ {
+ throw "internal error: cleanup_member_name_mapping() called for wrong struct";
+ }
+
+ member_mapping_scopes.pop_back();
+}
+
+string t_netstd_generator::get_mapped_member_name(string name)
+{
+ if (!member_mapping_scopes.empty())
+ {
+ member_mapping_scope& active = member_mapping_scopes.back();
+ map<string, string>::iterator iter = active.mapping_table.find(name);
+ if (active.mapping_table.end() != iter)
+ {
+ return iter->second;
+ }
+ }
+
+ pverbose("no mapping for member %s\n", name.c_str());
+ return name;
+}
+
+void t_netstd_generator::prepare_member_name_mapping(t_struct* tstruct)
+{
+ prepare_member_name_mapping(tstruct, tstruct->get_members(), tstruct->get_name());
+}
+
+void t_netstd_generator::prepare_member_name_mapping(void* scope, const vector<t_field*>& members, const string& structname)
+{
+ // begin new scope
+ member_mapping_scopes.emplace_back();
+ member_mapping_scope& active = member_mapping_scopes.back();
+ active.scope_member = scope;
+
+ // current C# generator policy:
+ // - prop names are always rendered with an Uppercase first letter
+ // - struct names are used as given
+ std::set<string> used_member_names;
+ vector<t_field*>::const_iterator iter;
+
+ // prevent name conflicts with struct (CS0542 error)
+ used_member_names.insert(structname);
+
+ // prevent name conflicts with known methods (THRIFT-2942)
+ used_member_names.insert("Read");
+ used_member_names.insert("Write");
+
+ for (iter = members.begin(); iter != members.end(); ++iter)
+ {
+ string oldname = (*iter)->get_name();
+ string newname = prop_name(*iter, true);
+ while (true)
+ {
+ // new name conflicts with another member
+ if (used_member_names.find(newname) != used_member_names.end())
+ {
+ pverbose("struct %s: member %s conflicts with another member\n", structname.c_str(), newname.c_str());
+ newname += '_';
+ continue;
+ }
+
+ // add always, this helps us to detect edge cases like
+ // different spellings ("foo" and "Foo") within the same struct
+ pverbose("struct %s: member mapping %s => %s\n", structname.c_str(), oldname.c_str(), newname.c_str());
+ active.mapping_table[oldname] = newname;
+ used_member_names.insert(newname);
+ break;
+ }
+ }
+}
+
+string t_netstd_generator::prop_name(t_field* tfield, bool suppress_mapping)
+{
+ string name(tfield->get_name());
+ if (suppress_mapping)
+ {
+ name[0] = toupper(name[0]);
+ }
+ else
+ {
+ name = get_mapped_member_name(name);
+ }
+ return name;
+}
+
+string t_netstd_generator::type_name(t_type* ttype)
+{
+ while (ttype->is_typedef())
+ {
+ ttype = static_cast<t_typedef*>(ttype)->get_type();
+ }
+
+ if (ttype->is_base_type())
+ {
+ return base_type_name(static_cast<t_base_type*>(ttype));
+ }
+
+ if (ttype->is_map())
+ {
+ t_map* tmap = static_cast<t_map*>(ttype);
+ return "Dictionary<" + type_name(tmap->get_key_type()) + ", " + type_name(tmap->get_val_type()) + ">";
+ }
+
+ if (ttype->is_set())
+ {
+ t_set* tset = static_cast<t_set*>(ttype);
+ return "THashSet<" + type_name(tset->get_elem_type()) + ">";
+ }
+
+ if (ttype->is_list())
+ {
+ t_list* tlist = static_cast<t_list*>(ttype);
+ return "List<" + type_name(tlist->get_elem_type()) + ">";
+ }
+
+ t_program* program = ttype->get_program();
+ if (program != NULL && program != program_)
+ {
+ string ns = program->get_namespace("netstd");
+ if (!ns.empty())
+ {
+ return ns + "." + normalize_name(ttype->get_name());
+ }
+ }
+
+ return normalize_name(ttype->get_name());
+}
+
+string t_netstd_generator::base_type_name(t_base_type* tbase)
+{
+ switch (tbase->get_base())
+ {
+ case t_base_type::TYPE_VOID:
+ return "void";
+ case t_base_type::TYPE_STRING:
+ {
+ if (tbase->is_binary())
+ {
+ return "byte[]";
+ }
+ return "string";
+ }
+ case t_base_type::TYPE_BOOL:
+ return "bool";
+ case t_base_type::TYPE_I8:
+ return "sbyte";
+ case t_base_type::TYPE_I16:
+ return "short";
+ case t_base_type::TYPE_I32:
+ return "int";
+ case t_base_type::TYPE_I64:
+ return "long";
+ case t_base_type::TYPE_DOUBLE:
+ return "double";
+ default:
+ throw "compiler error: no C# name for base type " + t_base_type::t_base_name(tbase->get_base());
+ }
+}
+
+string t_netstd_generator::declare_field(t_field* tfield, bool init, string prefix)
+{
+ string result = type_name(tfield->get_type()) + " " + prefix + tfield->get_name();
+ if (init)
+ {
+ t_type* ttype = tfield->get_type();
+ while (ttype->is_typedef())
+ {
+ ttype = static_cast<t_typedef*>(ttype)->get_type();
+ }
+ if (ttype->is_base_type() && field_has_default(tfield))
+ {
+ std::ofstream dummy;
+ result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
+ }
+ else if (ttype->is_base_type())
+ {
+ t_base_type::t_base tbase = static_cast<t_base_type*>(ttype)->get_base();
+ switch (tbase)
+ {
+ case t_base_type::TYPE_VOID:
+ throw "NO T_VOID CONSTRUCT";
+ case t_base_type::TYPE_STRING:
+ result += " = null";
+ break;
+ case t_base_type::TYPE_BOOL:
+ result += " = false";
+ break;
+ case t_base_type::TYPE_I8:
+ case t_base_type::TYPE_I16:
+ case t_base_type::TYPE_I32:
+ case t_base_type::TYPE_I64:
+ result += " = 0";
+ break;
+ case t_base_type::TYPE_DOUBLE:
+ result += " = (double)0";
+ break;
+ }
+ }
+ else if (ttype->is_enum())
+ {
+ result += " = (" + type_name(ttype) + ")0";
+ }
+ else if (ttype->is_container())
+ {
+ result += " = new " + type_name(ttype) + "()";
+ }
+ else
+ {
+ result += " = new " + type_name(ttype) + "()";
+ }
+ }
+ return result + ";";
+}
+
+string t_netstd_generator::function_signature(t_function* tfunction, string prefix)
+{
+ t_type* ttype = tfunction->get_returntype();
+ return type_name(ttype) + " " + normalize_name(prefix + tfunction->get_name()) + "(" + argument_list(tfunction->get_arglist()) + ")";
+}
+
+string t_netstd_generator::function_signature_async(t_function* tfunction, string prefix)
+{
+ t_type* ttype = tfunction->get_returntype();
+ string task = "Task";
+ if (!ttype->is_void())
+ {
+ task += "<" + type_name(ttype) + ">";
+ }
+
+ string result = task + " " + normalize_name(prefix + tfunction->get_name()) + "Async(";
+ string args = argument_list(tfunction->get_arglist());
+ result += args;
+ if (!args.empty())
+ {
+ result += ", ";
+ }
+ result += "CancellationToken cancellationToken = default(CancellationToken))";
+
+ return result;
+}
+
+string t_netstd_generator::argument_list(t_struct* tstruct)
+{
+ string result = "";
+ const vector<t_field*>& fields = tstruct->get_members();
+ vector<t_field*>::const_iterator f_iter;
+ bool first = true;
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ result += ", ";
+ }
+ result += type_name((*f_iter)->get_type()) + " " + normalize_name((*f_iter)->get_name());
+ }
+ return result;
+}
+
+string t_netstd_generator::type_to_enum(t_type* type)
+{
+ while (type->is_typedef())
+ {
+ type = static_cast<t_typedef*>(type)->get_type();
+ }
+
+ if (type->is_base_type())
+ {
+ t_base_type::t_base tbase = static_cast<t_base_type*>(type)->get_base();
+ switch (tbase)
+ {
+ case t_base_type::TYPE_VOID:
+ throw "NO T_VOID CONSTRUCT";
+ case t_base_type::TYPE_STRING:
+ return "TType.String";
+ case t_base_type::TYPE_BOOL:
+ return "TType.Bool";
+ case t_base_type::TYPE_I8:
+ return "TType.Byte";
+ case t_base_type::TYPE_I16:
+ return "TType.I16";
+ case t_base_type::TYPE_I32:
+ return "TType.I32";
+ case t_base_type::TYPE_I64:
+ return "TType.I64";
+ case t_base_type::TYPE_DOUBLE:
+ return "TType.Double";
+ }
+ }
+ else if (type->is_enum())
+ {
+ return "TType.I32";
+ }
+ else if (type->is_struct() || type->is_xception())
+ {
+ return "TType.Struct";
+ }
+ else if (type->is_map())
+ {
+ return "TType.Map";
+ }
+ else if (type->is_set())
+ {
+ return "TType.Set";
+ }
+ else if (type->is_list())
+ {
+ return "TType.List";
+ }
+
+ throw "INVALID TYPE IN type_to_enum: " + type->get_name();
+}
+
+void t_netstd_generator::generate_netstd_docstring_comment(ostream& out, string contents)
+{
+ docstring_comment(out, "/// <summary>" + endl, "/// ", contents, "/// </summary>" + endl);
+}
+
+void t_netstd_generator::generate_netstd_doc(ostream& out, t_field* field)
+{
+ if (field->get_type()->is_enum())
+ {
+ string combined_message = field->get_doc() + endl + "<seealso cref=\"" + get_enum_class_name(field->get_type()) + "\"/>";
+ generate_netstd_docstring_comment(out, combined_message);
+ }
+ else
+ {
+ generate_netstd_doc(out, static_cast<t_doc*>(field));
+ }
+}
+
+void t_netstd_generator::generate_netstd_doc(ostream& out, t_doc* tdoc)
+{
+ if (tdoc->has_doc())
+ {
+ generate_netstd_docstring_comment(out, tdoc->get_doc());
+ }
+}
+
+void t_netstd_generator::generate_netstd_doc(ostream& out, t_function* tfunction)
+{
+ if (tfunction->has_doc())
+ {
+ stringstream ps;
+ const vector<t_field*>& fields = tfunction->get_arglist()->get_members();
+ vector<t_field*>::const_iterator p_iter;
+ for (p_iter = fields.begin(); p_iter != fields.end(); ++p_iter)
+ {
+ t_field* p = *p_iter;
+ ps << endl << "<param name=\"" << p->get_name() << "\">";
+ if (p->has_doc())
+ {
+ string str = p->get_doc();
+ str.erase(remove(str.begin(), str.end(), '\n'), str.end());
+ ps << str;
+ }
+ ps << "</param>";
+ }
+
+ docstring_comment(out,
+ "",
+ "/// ",
+ "<summary>" + endl + tfunction->get_doc() + "</summary>" + ps.str(),
+ "");
+ }
+}
+
+void t_netstd_generator::docstring_comment(ostream& out, const string& comment_start, const string& line_prefix, const string& contents, const string& comment_end)
+{
+ if (comment_start != "")
+ {
+ out << indent() << comment_start;
+ }
+
+ stringstream docs(contents, std::ios_base::in);
+
+ while (!(docs.eof() || docs.fail()))
+ {
+ char line[1024];
+ docs.getline(line, 1024);
+
+ // Just prnt a newline when the line & prefix are empty.
+ if (strlen(line) == 0 && line_prefix == "" && !docs.eof())
+ {
+ out << endl;
+ }
+ else if (strlen(line) > 0 || !docs.eof())
+ { // skip the empty last line
+ out << indent() << line_prefix << line << endl;
+ }
+ }
+ if (comment_end != "")
+ {
+ out << indent() << comment_end;
+ }
+}
+
+string t_netstd_generator::get_enum_class_name(t_type* type)
+{
+ string package = "";
+ t_program* program = type->get_program();
+ if (program != NULL && program != program_)
+ {
+ package = program->get_namespace("netstd") + ".";
+ }
+ return package + type->get_name();
+}
+
+THRIFT_REGISTER_GENERATOR(
+ netstd,
+ "C#",
+ " wcf: Adds bindings for WCF to generated classes.\n"
+ " serial: Add serialization support to generated classes.\n"
+ " union: Use new union typing, which includes a static read function for union types.\n"
+)
diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.h b/compiler/cpp/src/thrift/generate/t_netstd_generator.h
new file mode 100644
index 0000000..fd9e6c0
--- /dev/null
+++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.h
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+#include <cassert>
+
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <vector>
+#include <cctype>
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sstream>
+
+#include "thrift/platform.h"
+#include "thrift/generate/t_oop_generator.h"
+
+using std::map;
+using std::ostream;
+using std::ostringstream;
+using std::string;
+using std::stringstream;
+using std::vector;
+
+static const string endl = "\n"; // avoid ostream << std::endl flushes
+
+class t_netstd_generator : public t_oop_generator
+{
+
+ struct member_mapping_scope
+ {
+ public:
+ member_mapping_scope() : scope_member(0) { }
+ void* scope_member;
+ map<string, string> mapping_table;
+ };
+
+public:
+ t_netstd_generator(t_program* program, const map<string, string>& parsed_options, const string& option_string);
+
+ bool is_wcf_enabled() const;
+ bool is_nullable_enabled() const;
+ bool is_hashcode_enabled() const;
+ bool is_serialize_enabled() const;
+ bool is_union_enabled() const;
+ map<string, int> get_keywords_list() const;
+
+ // overrides
+ void init_generator();
+ void close_generator();
+ void generate_consts(vector<t_const*> consts);
+ void generate_consts(ostream& out, vector<t_const*> consts);
+ void generate_typedef(t_typedef* ttypedef);
+ void generate_enum(t_enum* tenum);
+ void generate_enum(ostream& out, t_enum* tenum);
+ void generate_struct(t_struct* tstruct);
+ void generate_xception(t_struct* txception);
+ void generate_service(t_service* tservice);
+
+ void generate_property(ostream& out, t_field* tfield, bool isPublic, bool generateIsset);
+ void generate_netstd_property(ostream& out, t_field* tfield, bool isPublic, bool includeIsset = true, string fieldPrefix = "");
+ bool print_const_value(ostream& out, string name, t_type* type, t_const_value* value, bool in_static, bool defval = false, bool needtype = false);
+ string render_const_value(ostream& out, string name, t_type* type, t_const_value* value);
+ void print_const_constructor(ostream& out, vector<t_const*> consts);
+ void print_const_def_value(ostream& out, string name, t_type* type, t_const_value* value);
+ void generate_netstd_struct(t_struct* tstruct, bool is_exception);
+ void generate_netstd_union(t_struct* tunion);
+ void generate_netstd_struct_definition(ostream& out, t_struct* tstruct, bool is_xception = false, bool in_class = false, bool is_result = false);
+ void generate_netstd_union_definition(ostream& out, t_struct* tunion);
+ void generate_netstd_union_class(ostream& out, t_struct* tunion, t_field* tfield);
+ void generate_netstd_wcffault(ostream& out, t_struct* tstruct);
+ void generate_netstd_struct_reader(ostream& out, t_struct* tstruct);
+ void generate_netstd_struct_result_writer(ostream& out, t_struct* tstruct);
+ void generate_netstd_struct_writer(ostream& out, t_struct* tstruct);
+ void generate_netstd_struct_tostring(ostream& out, t_struct* tstruct);
+ void generate_netstd_struct_equals(ostream& out, t_struct* tstruct);
+ void generate_netstd_struct_hashcode(ostream& out, t_struct* tstruct);
+ void generate_netstd_union_reader(ostream& out, t_struct* tunion);
+ void generate_function_helpers(ostream& out, t_function* tfunction);
+ void generate_service_interface(ostream& out, t_service* tservice);
+ void generate_service_helpers(ostream& out, t_service* tservice);
+ void generate_service_client(ostream& out, t_service* tservice);
+ void generate_service_server(ostream& out, t_service* tservice);
+ void generate_process_function_async(ostream& out, t_service* tservice, t_function* function);
+ void generate_deserialize_field(ostream& out, t_field* tfield, string prefix = "", bool is_propertyless = false);
+ void generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
+ void generate_deserialize_container(ostream& out, t_type* ttype, string prefix = "");
+ void generate_deserialize_set_element(ostream& out, t_set* tset, string prefix = "");
+ void generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix = "");
+ void generate_deserialize_list_element(ostream& out, t_list* list, string prefix = "");
+ void generate_serialize_field(ostream& out, t_field* tfield, string prefix = "", bool is_propertyless = false);
+ void generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
+ void generate_serialize_container(ostream& out, t_type* ttype, string prefix = "");
+ void generate_serialize_map_element(ostream& out, t_map* tmap, string iter, string map);
+ void generate_serialize_set_element(ostream& out, t_set* tmap, string iter);
+ void generate_serialize_list_element(ostream& out, t_list* tlist, string iter);
+ void generate_netstd_doc(ostream& out, t_field* field);
+ void generate_netstd_doc(ostream& out, t_doc* tdoc);
+ void generate_netstd_doc(ostream& out, t_function* tdoc);
+ void generate_netstd_docstring_comment(ostream& out, string contents);
+ void docstring_comment(ostream& out, const string& comment_start, const string& line_prefix, const string& contents, const string& comment_end);
+ void start_netstd_namespace(ostream& out);
+ void end_netstd_namespace(ostream& out);
+
+ string netstd_type_usings() const;
+ string netstd_thrift_usings() const;
+
+ string type_name(t_type* ttype);
+ string base_type_name(t_base_type* tbase);
+ string declare_field(t_field* tfield, bool init = false, string prefix = "");
+ string function_signature_async(t_function* tfunction, string prefix = "");
+ string function_signature(t_function* tfunction, string prefix = "");
+ string argument_list(t_struct* tstruct);
+ string type_to_enum(t_type* ttype);
+ string prop_name(t_field* tfield, bool suppress_mapping = false);
+ string get_enum_class_name(t_type* type);
+
+private:
+ string namespace_name_;
+ string namespace_dir_;
+
+ bool nullable_;
+ bool union_;
+ bool hashcode_;
+ bool serialize_;
+ bool wcf_;
+
+ string wcf_namespace_;
+ map<string, int> netstd_keywords;
+ vector<member_mapping_scope> member_mapping_scopes;
+
+ void init_keywords();
+ string normalize_name(string name);
+ string make_valid_csharp_identifier(string const& fromName);
+ void prepare_member_name_mapping(t_struct* tstruct);
+ void prepare_member_name_mapping(void* scope, const vector<t_field*>& members, const string& structname);
+ void cleanup_member_name_mapping(void* scope);
+ string get_mapped_member_name(string oldname);
+};
diff --git a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
index 0ec81ba..a3781e8 100644
--- a/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
@@ -65,19 +65,19 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_program();
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_program() override;
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
std::string render_const_value(t_type* type, t_const_value* value);
bool struct_member_persistent(t_field* tmember);
diff --git a/compiler/cpp/src/thrift/generate/t_perl_generator.cc b/compiler/cpp/src/thrift/generate/t_perl_generator.cc
index 8924a76..80729cb 100644
--- a/compiler/cpp/src/thrift/generate/t_perl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_perl_generator.cc
@@ -66,19 +66,19 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
std::string render_const_value(t_type* type, t_const_value* value);
@@ -152,7 +152,7 @@
std::string argument_list(t_struct* tstruct);
std::string type_to_enum(t_type* ttype);
- std::string autogen_comment() {
+ std::string autogen_comment() override {
return std::string("#\n") + "# Autogenerated by Thrift Compiler (" + THRIFT_VERSION + ")\n"
+ "#\n" + "# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n" + "#\n";
}
diff --git a/compiler/cpp/src/thrift/generate/t_php_generator.cc b/compiler/cpp/src/thrift/generate/t_php_generator.cc
index 50a4415..79bd5a2 100644
--- a/compiler/cpp/src/thrift/generate/t_php_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_php_generator.cc
@@ -99,7 +99,7 @@
escape_['$'] = "\\$";
}
- virtual std::string indent_str() const {
+ std::string indent_str() const override {
return " ";
}
@@ -109,19 +109,19 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_consts(vector<t_const*> consts);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_consts(vector<t_const*> consts) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
std::string render_const_value(t_type* type, t_const_value* value);
@@ -284,9 +284,9 @@
}
// Transform the java-style namespace into a path.
- for (std::string::iterator it = ns.begin(); it != ns.end(); ++it) {
- if (*it == '.') {
- *it = '/';
+ for (char & n : ns) {
+ if (n == '.') {
+ n = '/';
}
}
@@ -304,8 +304,8 @@
vector<string> x = split(str, '_');
- for (size_t i = 0; i < x.size(); ++i) {
- classe = classe + capitalize(x[i]);
+ for (const auto & i : x) {
+ classe = classe + capitalize(i);
}
return classe;
@@ -420,8 +420,8 @@
vector<string> NSx = split(php_namespace_suffix(get_program()), '\\');
package_dir_ = get_out_dir();
- for (size_t i = 0; i < NSx.size(); ++i) {
- package_dir_ = package_dir_ + "/" + NSx[i] + "/";
+ for (const auto & i : NSx) {
+ package_dir_ = package_dir_ + "/" + i + "/";
MKDIR(package_dir_.c_str());
}
diff --git a/compiler/cpp/src/thrift/generate/t_py_generator.cc b/compiler/cpp/src/thrift/generate/t_py_generator.cc
index f0a153c..83462f4 100644
--- a/compiler/cpp/src/thrift/generate/t_py_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_py_generator.cc
@@ -136,7 +136,7 @@
}
}
- virtual std::string indent_str() const {
+ std::string indent_str() const override {
return " ";
}
@@ -144,20 +144,20 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_forward_declaration(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_forward_declaration(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
std::string render_const_value(t_type* type, t_const_value* value);
@@ -335,7 +335,7 @@
std::string module_;
protected:
- virtual std::set<std::string> lang_keywords() const {
+ std::set<std::string> lang_keywords() const override {
std::string keywords[] = { "False", "None", "True", "and", "as", "assert", "break", "class",
"continue", "def", "del", "elif", "else", "except", "exec", "finally", "for", "from",
"global", "if", "import", "in", "is", "lambda", "nonlocal", "not", "or", "pass", "print",
@@ -415,8 +415,8 @@
string t_py_generator::render_includes() {
const vector<t_program*>& includes = program_->get_includes();
string result = "";
- for (size_t i = 0; i < includes.size(); ++i) {
- result += "import " + get_real_py_module(includes[i], gen_twisted_, package_prefix_) + ".ttypes\n";
+ for (auto include : includes) {
+ result += "import " + get_real_py_module(include, gen_twisted_, package_prefix_) + ".ttypes\n";
}
return result;
}
@@ -1624,7 +1624,6 @@
<< (*f_iter)->get_name() << "(";
t_struct* arg_struct = (*f_iter)->get_arglist();
const std::vector<t_field*>& args = arg_struct->get_members();
- vector<t_field*>::const_iterator a_iter;
std::vector<t_field*>::size_type num_args = args.size();
bool first = true;
for (std::vector<t_field*>::size_type i = 0; i < num_args; ++i) {
@@ -1730,7 +1729,6 @@
t_struct* arg_struct = (*f_iter)->get_arglist();
const std::vector<t_field*>& args = arg_struct->get_members();
- vector<t_field*>::const_iterator a_iter;
std::vector<t_field*>::size_type num_args = args.size();
f_remote << "if cmd == '" << (*f_iter)->get_name() << "':" << endl;
@@ -1833,6 +1831,13 @@
f_service_ << indent() << "self._processMap[\"" << (*f_iter)->get_name()
<< "\"] = Processor.process_" << (*f_iter)->get_name() << endl;
}
+ f_service_ << indent() << "self._on_message_begin = None" << endl;
+ indent_down();
+ f_service_ << endl;
+
+ f_service_ << indent() << "def on_message_begin(self, func):" << endl;
+ indent_up();
+ f_service_ << indent() << "self._on_message_begin = func" << endl;
indent_down();
f_service_ << endl;
@@ -1841,6 +1846,10 @@
indent_up();
f_service_ << indent() << "(name, type, seqid) = iprot.readMessageBegin()" << endl;
+ f_service_ << indent() << "if self._on_message_begin:" << endl;
+ indent_up();
+ f_service_ << indent() << "self._on_message_begin(name, type, seqid)" << endl;
+ indent_down();
// TODO(mcslee): validate message
@@ -2609,7 +2618,7 @@
string signature = tfunction->get_name() + "(";
if (!(gen_zope_interface_ && interface)) {
- pre.push_back("self");
+ pre.emplace_back("self");
}
signature += argument_list(tfunction->get_arglist(), &pre, &post) + ")";
diff --git a/compiler/cpp/src/thrift/generate/t_rb_generator.cc b/compiler/cpp/src/thrift/generate/t_rb_generator.cc
index 13ea249..61c3481 100644
--- a/compiler/cpp/src/thrift/generate/t_rb_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rb_generator.cc
@@ -102,21 +102,21 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_forward_declaration(t_struct* tstruct);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_forward_declaration(t_struct* tstruct) override;
void generate_union(t_struct* tunion);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
t_rb_ofstream& render_const_value(t_rb_ofstream& out, t_type* type, t_const_value* value);
@@ -307,15 +307,15 @@
string t_rb_generator::render_includes() {
const vector<t_program*>& includes = program_->get_includes();
string result = "";
- for (size_t i = 0; i < includes.size(); ++i) {
+ for (auto include : includes) {
if (namespaced_) {
- t_program* included = includes[i];
+ t_program* included = include;
std::string included_require_prefix
= rb_namespace_to_path_prefix(included->get_namespace("rb"));
std::string included_name = included->get_name();
result += "require '" + included_require_prefix + underscore(included_name) + "_types'\n";
} else {
- result += "require '" + underscore(includes[i]->get_name()) + "_types'\n";
+ result += "require '" + underscore(include->get_name()) + "_types'\n";
}
}
if (includes.size() > 0) {
@@ -763,8 +763,8 @@
}
void t_rb_generator::begin_namespace(t_rb_ofstream& out, vector<std::string> modules) {
- for (vector<std::string>::iterator m_iter = modules.begin(); m_iter != modules.end(); ++m_iter) {
- out.indent() << "module " << *m_iter << endl;
+ for (auto & module : modules) {
+ out.indent() << "module " << module << endl;
out.indent_up();
}
}
@@ -1140,8 +1140,8 @@
string t_rb_generator::full_type_name(const t_type* ttype) {
string prefix = "::";
vector<std::string> modules = ruby_modules(ttype->get_program());
- for (vector<std::string>::iterator m_iter = modules.begin(); m_iter != modules.end(); ++m_iter) {
- prefix += *m_iter + "::";
+ for (auto & module : modules) {
+ prefix += module + "::";
}
return prefix + type_name(ttype);
}
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
index 9843d7a..f6b4b6d 100644
--- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
@@ -74,19 +74,19 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
private:
// struct type
@@ -550,20 +550,17 @@
f_gen_ << endl;
// add standard includes
- f_gen_ << "extern crate ordered_float;" << endl;
f_gen_ << "extern crate thrift;" << endl;
- f_gen_ << "extern crate try_from;" << endl;
f_gen_ << endl;
- f_gen_ << "use ordered_float::OrderedFloat;" << endl;
+ f_gen_ << "use thrift::OrderedFloat;" << endl;
f_gen_ << "use std::cell::RefCell;" << endl;
f_gen_ << "use std::collections::{BTreeMap, BTreeSet};" << endl;
- f_gen_ << "use std::convert::From;" << endl;
+ f_gen_ << "use std::convert::{From, TryFrom};" << endl;
f_gen_ << "use std::default::Default;" << endl;
f_gen_ << "use std::error::Error;" << endl;
f_gen_ << "use std::fmt;" << endl;
f_gen_ << "use std::fmt::{Display, Formatter};" << endl;
f_gen_ << "use std::rc::Rc;" << endl;
- f_gen_ << "use try_from::TryFrom;" << endl;
f_gen_ << endl;
f_gen_ << "use thrift::{ApplicationError, ApplicationErrorKind, ProtocolError, ProtocolErrorKind, TThriftClient};" << endl;
f_gen_ << "use thrift::protocol::{TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType, TInputProtocol, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType};" << endl;
@@ -932,9 +929,9 @@
f_gen_ << "impl TryFrom<i32> for " << enum_name << " {" << endl;
indent_up();
- f_gen_ << indent() << "type Err = thrift::Error;";
+ f_gen_ << indent() << "type Error = thrift::Error;";
- f_gen_ << indent() << "fn try_from(i: i32) -> Result<Self, Self::Err> {" << endl;
+ f_gen_ << indent() << "fn try_from(i: i32) -> Result<Self, Self::Error> {" << endl;
indent_up();
f_gen_ << indent() << "match i {" << endl;
@@ -3285,8 +3282,8 @@
string t_rs_generator::rust_enum_variant_name(const string &name) {
bool all_uppercase = true;
- for (size_t i = 0; i < name.size(); i++) {
- if (isalnum(name[i]) && islower(name[i])) {
+ for (char i : name) {
+ if (isalnum(i) && islower(i)) {
all_uppercase = false;
break;
}
diff --git a/compiler/cpp/src/thrift/generate/t_st_generator.cc b/compiler/cpp/src/thrift/generate/t_st_generator.cc
index 595a949..bc95feb 100644
--- a/compiler/cpp/src/thrift/generate/t_st_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_st_generator.cc
@@ -71,19 +71,19 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_const(t_const* tconst);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_const(t_const* tconst) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
void generate_class_side_definition();
void generate_force_consts();
@@ -233,9 +233,9 @@
string cat = program_->get_namespace("smalltalk.category");
// For compatibility with the Thrift grammar, the category must
// be punctuated by dots. Replaces them with dashes here.
- for (string::iterator iter = cat.begin(); iter != cat.end(); ++iter) {
- if (*iter == '.') {
- *iter = '-';
+ for (char & iter : cat) {
+ if (iter == '.') {
+ iter = '-';
}
}
return cat.size() ? cat : "Generated-" + class_name();
diff --git a/compiler/cpp/src/thrift/generate/t_swift_generator.cc b/compiler/cpp/src/thrift/generate/t_swift_generator.cc
index 31db04d..eb746c1 100644
--- a/compiler/cpp/src/thrift/generate/t_swift_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_swift_generator.cc
@@ -94,20 +94,20 @@
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
- void generate_consts(vector<t_const*> consts);
+ void generate_consts(vector<t_const*> consts) override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
- void generate_struct(t_struct* tstruct);
- void generate_xception(t_struct* txception);
- void generate_service(t_service* tservice);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
+ void generate_struct(t_struct* tstruct) override;
+ void generate_xception(t_struct* txception) override;
+ void generate_service(t_service* tservice) override;
void render_const_value(ostream& out,
@@ -336,7 +336,7 @@
string t_swift_generator::swift_imports() {
vector<string> includes_list;
- includes_list.push_back("Foundation");
+ includes_list.emplace_back("Foundation");
ostringstream includes;
@@ -347,8 +347,8 @@
if (namespaced_) {
const vector<t_program*>& program_includes = program_->get_includes();
- for (size_t i = 0; i < program_includes.size(); ++i) {
- includes << ("import " + get_real_swift_module(program_includes[i])) << endl;
+ for (auto program_include : program_includes) {
+ includes << ("import " + get_real_swift_module(program_include)) << endl;
}
}
includes << endl;
@@ -364,10 +364,10 @@
string t_swift_generator::swift_thrift_imports() {
vector<string> includes_list;
- includes_list.push_back("Thrift");
+ includes_list.emplace_back("Thrift");
if (gen_cocoa_ && promise_kit_) {
- includes_list.push_back("PromiseKit");
+ includes_list.emplace_back("PromiseKit");
}
ostringstream includes;
diff --git a/compiler/cpp/src/thrift/generate/t_xml_generator.cc b/compiler/cpp/src/thrift/generate/t_xml_generator.cc
index 35fed14..b669293 100644
--- a/compiler/cpp/src/thrift/generate/t_xml_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_xml_generator.cc
@@ -79,20 +79,20 @@
out_dir_base_ = "gen-xml";
}
- virtual ~t_xml_generator() {}
+ ~t_xml_generator() override = default;
- void init_generator();
- void close_generator();
- void generate_program();
+ void init_generator() override;
+ void close_generator() override;
+ void generate_program() override;
void iterate_program(t_program* program);
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum);
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override;
void generate_function(t_function* tfunc);
void generate_field(t_field* field);
- void generate_service(t_service* tservice);
- void generate_struct(t_struct* tstruct);
+ void generate_service(t_service* tservice) override;
+ void generate_struct(t_struct* tstruct) override;
void generate_annotations(std::map<std::string, std::string> annotations);
@@ -245,8 +245,8 @@
string t_xml_generator::escape_xml_string(const string& input) {
std::ostringstream ss;
- for (std::string::const_iterator iter = input.begin(); iter != input.end(); iter++) {
- switch (*iter) {
+ for (char iter : input) {
+ switch (iter) {
case '&':
ss << "&";
break;
@@ -263,7 +263,7 @@
ss << ">";
break;
default:
- ss << *iter;
+ ss << iter;
break;
}
}
diff --git a/compiler/cpp/src/thrift/generate/t_xsd_generator.cc b/compiler/cpp/src/thrift/generate/t_xsd_generator.cc
index e487ffc..379e5a4 100644
--- a/compiler/cpp/src/thrift/generate/t_xsd_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_xsd_generator.cc
@@ -59,24 +59,24 @@
out_dir_base_ = "gen-xsd";
}
- virtual ~t_xsd_generator() {}
+ ~t_xsd_generator() override = default;
/**
* Init and close methods
*/
- void init_generator();
- void close_generator();
+ void init_generator() override;
+ void close_generator() override;
/**
* Program-level generation functions
*/
- void generate_typedef(t_typedef* ttypedef);
- void generate_enum(t_enum* tenum) { (void)tenum; }
+ void generate_typedef(t_typedef* ttypedef) override;
+ void generate_enum(t_enum* tenum) override { (void)tenum; }
- void generate_service(t_service* tservice);
- void generate_struct(t_struct* tstruct);
+ void generate_service(t_service* tservice) override;
+ void generate_struct(t_struct* tstruct) override;
private:
void generate_element(std::ostream& out,
diff --git a/compiler/cpp/src/thrift/logging.cc b/compiler/cpp/src/thrift/logging.cc
index f821f5f..4811c4e 100644
--- a/compiler/cpp/src/thrift/logging.cc
+++ b/compiler/cpp/src/thrift/logging.cc
@@ -17,17 +17,12 @@
* under the License.
*/
-/**
- * Logging functions copied from main.cc to avoid link errors for plugins
- */
-
#include "thrift/logging.h"
#include "thrift/globals.h"
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
-// TODO: make plugins accept log options from main compiler
int g_debug = 0;
int g_warn = 1;
int g_verbose = 0;
diff --git a/compiler/cpp/src/thrift/main.cc b/compiler/cpp/src/thrift/main.cc
index cdc171c..5b69dc5 100644
--- a/compiler/cpp/src/thrift/main.cc
+++ b/compiler/cpp/src/thrift/main.cc
@@ -53,9 +53,6 @@
#include "thrift/parse/t_scope.h"
#include "thrift/generate/t_generator.h"
#include "thrift/audit/t_audit.h"
-#ifdef THRIFT_ENABLE_PLUGIN
-#include "thrift/plugin/plugin_output.h"
-#endif
#include "thrift/version.h"
@@ -171,7 +168,7 @@
#ifdef _WIN32
char buf[MAX_PATH];
char* basename;
- DWORD len = GetFullPathName(path, MAX_PATH, buf, &basename);
+ DWORD len = GetFullPathNameA(path, MAX_PATH, buf, &basename);
if (len == 0 || len > MAX_PATH - 1) {
strcpy(resolved_path, path);
} else {
@@ -986,11 +983,11 @@
// Oooohh, recursive code generation, hot!!
if (gen_recurse) {
const vector<t_program*>& includes = program->get_includes();
- for (size_t i = 0; i < includes.size(); ++i) {
+ for (auto include : includes) {
// Propagate output path from parent to child programs
- includes[i]->set_out_path(program->get_out_path(), program->is_out_path_absolute());
+ include->set_out_path(program->get_out_path(), program->is_out_path_absolute());
- generate(includes[i], generator_strings);
+ generate(include, generator_strings);
}
}
@@ -1007,26 +1004,8 @@
t_generator* generator = t_generator_registry::get_generator(program, *iter);
if (generator == NULL) {
-#ifdef THRIFT_ENABLE_PLUGIN
- switch (plugin_output::delegateToPlugin(program, *iter)) {
- case plugin_output::PLUGIN_NOT_FOUND:
- pwarning(1, "Unable to get a generator for \"%s\".\n", iter->c_str());
- g_generator_failure = true;
- break;
- case plugin_output::PLUGIN_FAILURE:
- pwarning(1, "Plugin generator for \"%s\" failed.\n", iter->c_str());
- g_generator_failure = true;
- break;
- case plugin_output::PLUGIN_SUCCEESS:
- break;
- default:
- assert(false);
- break;
- }
-#else
pwarning(1, "Unable to get a generator for \"%s\".\n", iter->c_str());
g_generator_failure = true;
-#endif
} else if (generator) {
generator->validate_input();
pverbose("Generating \"%s\"\n", iter->c_str());
@@ -1131,7 +1110,7 @@
fprintf(stderr, "Missing generator specification\n");
usage();
}
- generator_strings.push_back(arg);
+ generator_strings.emplace_back(arg);
} else if (strcmp(arg, "-I") == 0) {
// An argument of "-I\ asdf" is invalid and has unknown results
arg = argv[++i];
@@ -1140,7 +1119,7 @@
fprintf(stderr, "Missing Include directory\n");
usage();
}
- g_incl_searchpath.push_back(arg);
+ g_incl_searchpath.emplace_back(arg);
} else if ((strcmp(arg, "-o") == 0) || (strcmp(arg, "-out") == 0)) {
out_path_is_absolute = (strcmp(arg, "-out") == 0) ? true : false;
arg = argv[++i];
diff --git a/compiler/cpp/src/thrift/main.h b/compiler/cpp/src/thrift/main.h
index 54abb03..163b02e 100644
--- a/compiler/cpp/src/thrift/main.h
+++ b/compiler/cpp/src/thrift/main.h
@@ -106,7 +106,7 @@
* If new_form is NULL, old_form is assumed to be a language identifier, such as "cpp"
* If new_form is not NULL, both arguments are used exactly as given
*/
-void error_unsupported_namespace_decl(const char* old_form, const char* new_form = NULL);
+void error_unsupported_namespace_decl(const char* old_form, const char* new_form = nullptr);
/**
* Flex utilities
diff --git a/compiler/cpp/src/thrift/parse/parse.cc b/compiler/cpp/src/thrift/parse/parse.cc
index 01f7637..23db61c 100644
--- a/compiler/cpp/src/thrift/parse/parse.cc
+++ b/compiler/cpp/src/thrift/parse/parse.cc
@@ -23,11 +23,7 @@
#include "thrift/main.h"
t_type* t_type::get_true_type() {
- t_type* type = this;
- while (type->is_typedef()) {
- type = ((t_typedef*)type)->get_type();
- }
- return type;
+ return const_cast<t_type*>(const_cast<const t_type*>(this)->get_true_type());
}
const t_type* t_type::get_true_type() const {
diff --git a/compiler/cpp/src/thrift/parse/t_base_type.h b/compiler/cpp/src/thrift/parse/t_base_type.h
index 71398ba..ca2b0f6 100644
--- a/compiler/cpp/src/thrift/parse/t_base_type.h
+++ b/compiler/cpp/src/thrift/parse/t_base_type.h
@@ -49,11 +49,11 @@
t_base get_base() const { return base_; }
- bool is_void() const { return base_ == TYPE_VOID; }
+ bool is_void() const override { return base_ == TYPE_VOID; }
- bool is_string() const { return base_ == TYPE_STRING; }
+ bool is_string() const override { return base_ == TYPE_STRING; }
- bool is_bool() const { return base_ == TYPE_BOOL; }
+ bool is_bool() const override { return base_ == TYPE_BOOL; }
void set_string_list(bool val) { string_list_ = val; }
@@ -61,7 +61,7 @@
void set_binary(bool val) { binary_ = val; }
- bool is_binary() const { return binary_ && (base_ == TYPE_STRING); }
+ bool is_binary() const override { return binary_ && (base_ == TYPE_STRING); }
void set_string_enum(bool val) { string_enum_ = val; }
@@ -71,7 +71,7 @@
const std::vector<std::string>& get_string_enum_vals() const { return string_enum_vals_; }
- bool is_base_type() const { return true; }
+ bool is_base_type() const override { return true; }
static std::string t_base_name(t_base tbase) {
switch (tbase) {
diff --git a/compiler/cpp/src/thrift/parse/t_const_value.h b/compiler/cpp/src/thrift/parse/t_const_value.h
index 6a114cf..5b8156f 100644
--- a/compiler/cpp/src/thrift/parse/t_const_value.h
+++ b/compiler/cpp/src/thrift/parse/t_const_value.h
@@ -26,11 +26,6 @@
#include <vector>
#include <string>
-namespace plugin_output {
-template <typename From, typename To>
-void convert(From*, To&);
-}
-
/**
* A const value is something parsed that could be a map, set, list, struct
* or whatever.
@@ -51,11 +46,11 @@
enum t_const_value_type { CV_INTEGER, CV_DOUBLE, CV_STRING, CV_MAP, CV_LIST, CV_IDENTIFIER, CV_UNKNOWN };
- t_const_value() : intVal_(0), doubleVal_(0.0f), enum_((t_enum*)0), valType_(CV_UNKNOWN) {}
+ t_const_value() : intVal_(0), doubleVal_(0.0f), enum_((t_enum*)nullptr), valType_(CV_UNKNOWN) {}
- t_const_value(int64_t val) : doubleVal_(0.0f), enum_((t_enum*)0), valType_(CV_UNKNOWN) { set_integer(val); }
+ t_const_value(int64_t val) : doubleVal_(0.0f), enum_((t_enum*)nullptr), valType_(CV_UNKNOWN) { set_integer(val); }
- t_const_value(std::string val) : intVal_(0), doubleVal_(0.0f), enum_((t_enum*)0), valType_(CV_UNKNOWN) { set_string(val); }
+ t_const_value(std::string val) : intVal_(0), doubleVal_(0.0f), enum_((t_enum*)nullptr), valType_(CV_UNKNOWN) { set_string(val); }
void set_string(std::string val) {
valType_ = CV_STRING;
@@ -71,7 +66,7 @@
int64_t get_integer() const {
if (valType_ == CV_IDENTIFIER) {
- if (enum_ == NULL) {
+ if (enum_ == nullptr) {
throw "have identifier \"" + get_identifier() + "\", but unset enum on line!";
}
std::string identifier = get_identifier();
@@ -80,7 +75,7 @@
identifier = identifier.substr(dot + 1);
}
t_enum_value* val = enum_->get_constant_by_name(identifier);
- if (val == NULL) {
+ if (val == nullptr) {
throw "Unable to find enum value \"" + identifier + "\" in enum \"" + enum_->get_name()
+ "\"";
}
@@ -204,10 +199,6 @@
t_enum* enum_;
t_const_value_type valType_;
-
- // to read enum_
- template <typename From, typename To>
- friend void plugin_output::convert(From*, To&);
};
#endif
diff --git a/compiler/cpp/src/thrift/parse/t_container.h b/compiler/cpp/src/thrift/parse/t_container.h
index 5bdab70..a124d31 100644
--- a/compiler/cpp/src/thrift/parse/t_container.h
+++ b/compiler/cpp/src/thrift/parse/t_container.h
@@ -26,7 +26,7 @@
public:
t_container() : cpp_name_(), has_cpp_name_(false) {}
- virtual ~t_container() {}
+ ~t_container() override = default;
void set_cpp_name(std::string cpp_name) {
cpp_name_ = cpp_name;
@@ -37,7 +37,7 @@
std::string get_cpp_name() const { return cpp_name_; }
- bool is_container() const { return true; }
+ bool is_container() const override { return true; }
private:
std::string cpp_name_;
diff --git a/compiler/cpp/src/thrift/parse/t_doc.h b/compiler/cpp/src/thrift/parse/t_doc.h
index 7bcb8f5..0df893e 100644
--- a/compiler/cpp/src/thrift/parse/t_doc.h
+++ b/compiler/cpp/src/thrift/parse/t_doc.h
@@ -31,7 +31,7 @@
public:
t_doc() : has_doc_(false) {}
- virtual ~t_doc() {}
+ virtual ~t_doc() = default;
void set_doc(const std::string& doc) {
doc_ = doc;
diff --git a/compiler/cpp/src/thrift/parse/t_enum.h b/compiler/cpp/src/thrift/parse/t_enum.h
index 9e23780..3f013ee 100644
--- a/compiler/cpp/src/thrift/parse/t_enum.h
+++ b/compiler/cpp/src/thrift/parse/t_enum.h
@@ -33,13 +33,13 @@
public:
t_enum(t_program* program) : t_type(program) {}
- void set_name(const std::string& name) { name_ = name; }
+ void set_name(const std::string& name) override { name_ = name; }
void append(t_enum_value* constant) { constants_.push_back(constant); }
const std::vector<t_enum_value*>& get_constants() const { return constants_; }
- t_enum_value* get_constant_by_name(const std::string& name) {
+ t_enum_value* get_constant_by_name(const std::string& name) const {
const std::vector<t_enum_value*>& enum_values = get_constants();
std::vector<t_enum_value*>::const_iterator c_iter;
for (c_iter = enum_values.begin(); c_iter != enum_values.end(); ++c_iter) {
@@ -47,10 +47,10 @@
return *c_iter;
}
}
- return NULL;
+ return nullptr;
}
- t_enum_value* get_constant_by_value(int64_t value) {
+ t_enum_value* get_constant_by_value(int64_t value) const {
const std::vector<t_enum_value*>& enum_values = get_constants();
std::vector<t_enum_value*>::const_iterator c_iter;
for (c_iter = enum_values.begin(); c_iter != enum_values.end(); ++c_iter) {
@@ -58,15 +58,15 @@
return *c_iter;
}
}
- return NULL;
+ return nullptr;
}
- t_enum_value* get_min_value() {
+ t_enum_value* get_min_value() const {
const std::vector<t_enum_value*>& enum_values = get_constants();
std::vector<t_enum_value*>::const_iterator c_iter;
t_enum_value* min_value;
if (enum_values.size() == 0) {
- min_value = NULL;
+ min_value = nullptr;
} else {
int min_value_value;
min_value = enum_values.front();
@@ -81,12 +81,12 @@
return min_value;
}
- t_enum_value* get_max_value() {
+ t_enum_value* get_max_value() const {
const std::vector<t_enum_value*>& enum_values = get_constants();
std::vector<t_enum_value*>::const_iterator c_iter;
t_enum_value* max_value;
if (enum_values.size() == 0) {
- max_value = NULL;
+ max_value = nullptr;
} else {
int max_value_value;
max_value = enum_values.back();
@@ -101,7 +101,7 @@
return max_value;
}
- bool is_enum() const { return true; }
+ bool is_enum() const override { return true; }
private:
std::vector<t_enum_value*> constants_;
diff --git a/compiler/cpp/src/thrift/parse/t_enum_value.h b/compiler/cpp/src/thrift/parse/t_enum_value.h
index c0bf3ad..70eee86 100644
--- a/compiler/cpp/src/thrift/parse/t_enum_value.h
+++ b/compiler/cpp/src/thrift/parse/t_enum_value.h
@@ -34,7 +34,7 @@
public:
t_enum_value(std::string name, int value) : name_(name), value_(value) {}
- ~t_enum_value() {}
+ ~t_enum_value() override = default;
const std::string& get_name() const { return name_; }
diff --git a/compiler/cpp/src/thrift/parse/t_field.h b/compiler/cpp/src/thrift/parse/t_field.h
index c5f1f80..4be8770 100644
--- a/compiler/cpp/src/thrift/parse/t_field.h
+++ b/compiler/cpp/src/thrift/parse/t_field.h
@@ -41,10 +41,10 @@
: type_(type),
name_(name),
key_(0),
- value_(NULL),
+ value_(nullptr),
xsd_optional_(false),
xsd_nillable_(false),
- xsd_attrs_(NULL),
+ xsd_attrs_(nullptr),
reference_(false) {}
t_field(t_type* type, std::string name, int32_t key)
@@ -52,13 +52,13 @@
name_(name),
key_(key),
req_(T_OPT_IN_REQ_OUT),
- value_(NULL),
+ value_(nullptr),
xsd_optional_(false),
xsd_nillable_(false),
- xsd_attrs_(NULL),
+ xsd_attrs_(nullptr),
reference_(false) {}
- ~t_field() {}
+ ~t_field() override = default;
t_type* get_type() { return type_; }
@@ -92,6 +92,8 @@
t_struct* get_xsd_attrs() { return xsd_attrs_; }
+ const t_struct* get_xsd_attrs() const { return xsd_attrs_; }
+
/**
* Comparator to sort fields in ascending order by key.
* Make this a functor instead of a function to help GCC inline it.
@@ -105,7 +107,7 @@
std::map<std::string, std::string> annotations_;
- bool get_reference() { return reference_; }
+ bool get_reference() const { return reference_; }
void set_reference(bool reference) { reference_ = reference; }
diff --git a/compiler/cpp/src/thrift/parse/t_function.h b/compiler/cpp/src/thrift/parse/t_function.h
index 22d2609..d30c8a4 100644
--- a/compiler/cpp/src/thrift/parse/t_function.h
+++ b/compiler/cpp/src/thrift/parse/t_function.h
@@ -37,7 +37,7 @@
: returntype_(returntype),
name_(name),
arglist_(arglist),
- xceptions_(new t_struct(NULL)),
+ xceptions_(new t_struct(nullptr)),
own_xceptions_(true),
oneway_(oneway) {
if (oneway_ && (!returntype_->is_void())) {
@@ -64,7 +64,7 @@
}
}
- ~t_function() {
+ ~t_function() override {
if (own_xceptions_)
delete xceptions_;
}
diff --git a/compiler/cpp/src/thrift/parse/t_list.h b/compiler/cpp/src/thrift/parse/t_list.h
index acf6865..f0b896d 100644
--- a/compiler/cpp/src/thrift/parse/t_list.h
+++ b/compiler/cpp/src/thrift/parse/t_list.h
@@ -32,7 +32,7 @@
t_type* get_elem_type() const { return elem_type_; }
- bool is_list() const { return true; }
+ bool is_list() const override { return true; }
private:
t_type* elem_type_;
diff --git a/compiler/cpp/src/thrift/parse/t_map.h b/compiler/cpp/src/thrift/parse/t_map.h
index dd3f089..9614e68 100644
--- a/compiler/cpp/src/thrift/parse/t_map.h
+++ b/compiler/cpp/src/thrift/parse/t_map.h
@@ -35,7 +35,7 @@
t_type* get_val_type() const { return val_type_; }
- bool is_map() const { return true; }
+ bool is_map() const override { return true; }
private:
t_type* key_type_;
diff --git a/compiler/cpp/src/thrift/parse/t_program.h b/compiler/cpp/src/thrift/parse/t_program.h
index 43dd45a..13cb26e 100644
--- a/compiler/cpp/src/thrift/parse/t_program.h
+++ b/compiler/cpp/src/thrift/parse/t_program.h
@@ -65,10 +65,10 @@
scope_ = new t_scope();
}
- ~t_program() {
+ ~t_program() override {
if (scope_) {
delete scope_;
- scope_ = NULL;
+ scope_ = nullptr;
}
}
@@ -115,6 +115,8 @@
void add_service(t_service* ts) { services_.push_back(ts); }
// Programs to include
+ std::vector<t_program*>& get_includes() { return includes_; }
+
const std::vector<t_program*>& get_includes() const { return includes_; }
void set_out_path(std::string out_path, bool out_path_is_absolute) {
@@ -133,9 +135,9 @@
* @param t the type to test for collisions
* @return true if a certain collision was found, otherwise false
*/
- bool is_unique_typename(t_type* t) {
+ bool is_unique_typename(const t_type* t) const {
int occurrences = program_typename_count(this, t);
- for (std::vector<t_program*>::iterator it = includes_.begin(); it != includes_.end(); ++it) {
+ for (auto it = includes_.cbegin(); it != includes_.cend(); ++it) {
occurrences += program_typename_count(*it, t);
}
return 0 == occurrences;
@@ -147,7 +149,7 @@
* @param t the type to test for collisions
* @return the number of certain typename collisions
*/
- int program_typename_count(t_program* prog, t_type* t) {
+ int program_typename_count(const t_program* prog, const t_type* t) const {
int occurrences = 0;
occurrences += collection_typename_count(prog, prog->typedefs_, t);
occurrences += collection_typename_count(prog, prog->enums_, t);
@@ -164,9 +166,9 @@
* @return the number of certain typename collisions
*/
template <class T>
- int collection_typename_count(t_program* prog, T type_collection, t_type* t) {
+ int collection_typename_count(const t_program* prog, const T type_collection, const t_type* t) const {
int occurrences = 0;
- for (typename T::iterator it = type_collection.begin(); it != type_collection.end(); ++it)
+ for (auto it = type_collection.cbegin(); it != type_collection.cend(); ++it)
if (t != *it && 0 == t->get_name().compare((*it)->get_name()) && is_common_namespace(prog, t))
++occurrences;
return occurrences;
@@ -184,7 +186,7 @@
* @param t the type containing the typename match
* @return true if a collision within namespaces is found, otherwise false
*/
- bool is_common_namespace(t_program* prog, t_type* t) {
+ bool is_common_namespace(const t_program* prog, const t_type* t) const {
// Case 1: Typenames are in the same program [collision]
if (prog == t->get_program()) {
pwarning(1,
@@ -196,8 +198,8 @@
// Case 2: Both programs have identical namespace scope/name declarations [collision]
bool match = true;
- for (std::map<std::string, std::string>::iterator it = prog->namespaces_.begin();
- it != prog->namespaces_.end();
+ for (auto it = prog->namespaces_.cbegin();
+ it != prog->namespaces_.cend();
++it) {
if (0 == it->second.compare(t->get_program()->get_namespace(it->first))) {
pwarning(1,
@@ -213,8 +215,8 @@
match = false;
}
}
- for (std::map<std::string, std::string>::iterator it = t->get_program()->namespaces_.begin();
- it != t->get_program()->namespaces_.end();
+ for (auto it = t->get_program()->namespaces_.cbegin();
+ it != t->get_program()->namespaces_.cend();
++it) {
if (0 == it->second.compare(prog->get_namespace(it->first))) {
pwarning(1,
@@ -244,7 +246,9 @@
void set_namespace(std::string name) { namespace_ = name; }
// Scope accessor
- t_scope* scope() const { return scope_; }
+ t_scope* scope() { return scope_; }
+
+ const t_scope* scope() const { return scope_; }
// Includes
@@ -267,8 +271,6 @@
includes_.push_back(program);
}
- std::vector<t_program*>& get_includes() { return includes_; }
-
void set_include_prefix(std::string include_prefix) {
include_prefix_ = include_prefix;
@@ -284,7 +286,6 @@
if (language != "*") {
size_t sub_index = language.find('.');
std::string base_language = language.substr(0, sub_index);
- std::string sub_namespace;
if (base_language == "smalltalk") {
pwarning(1, "Namespace 'smalltalk' is deprecated. Use 'st' instead");
@@ -323,7 +324,7 @@
return std::string();
}
- const std::map<std::string, std::string>& get_all_namespaces(){
+ const std::map<std::string, std::string>& get_all_namespaces() const {
return namespaces_;
}
@@ -331,7 +332,16 @@
namespace_annotations_[language] = annotations;
}
- const std::map<std::string, std::string>& get_namespace_annotations(std::string language) {
+ const std::map<std::string, std::string>& get_namespace_annotations(const std::string& language) const {
+ auto it = namespace_annotations_.find(language);
+ if (namespace_annotations_.end() != it) {
+ return it->second;
+ }
+ static const std::map<std::string, std::string> emptyMap;
+ return emptyMap;
+ }
+
+ std::map<std::string, std::string>& get_namespace_annotations(const std::string& language) {
return namespace_annotations_[language];
}
@@ -339,11 +349,11 @@
void add_cpp_include(std::string path) { cpp_includes_.push_back(path); }
- const std::vector<std::string>& get_cpp_includes() { return cpp_includes_; }
+ const std::vector<std::string>& get_cpp_includes() const { return cpp_includes_; }
void add_c_include(std::string path) { c_includes_.push_back(path); }
- const std::vector<std::string>& get_c_includes() { return c_includes_; }
+ const std::vector<std::string>& get_c_includes() const { return c_includes_; }
private:
// File path
diff --git a/compiler/cpp/src/thrift/parse/t_scope.h b/compiler/cpp/src/thrift/parse/t_scope.h
index 6f160a5..a12c4df 100644
--- a/compiler/cpp/src/thrift/parse/t_scope.h
+++ b/compiler/cpp/src/thrift/parse/t_scope.h
@@ -33,11 +33,6 @@
#include "thrift/parse/t_list.h"
#include "thrift/parse/t_set.h"
-namespace plugin_output {
-template <typename From, typename To>
-void convert(From*, To&);
-}
-
/**
* This represents a variable scope used for looking up predefined types and
* services. Typically, a scope is associated with a t_program. Scopes are not
@@ -47,16 +42,34 @@
*/
class t_scope {
public:
- t_scope() {}
+ t_scope() = default;
void add_type(std::string name, t_type* type) { types_[name] = type; }
t_type* get_type(std::string name) { return types_[name]; }
+ const t_type* get_type(std::string name) const {
+ const auto it = types_.find(name);
+ if (types_.end() != it)
+ {
+ return it->second;
+ }
+ return nullptr;
+ }
+
void add_service(std::string name, t_service* service) { services_[name] = service; }
t_service* get_service(std::string name) { return services_[name]; }
+ const t_service* get_service(std::string name) const {
+ const auto it = services_.find(name);
+ if (services_.end() != it)
+ {
+ return it->second;
+ }
+ return nullptr;
+ }
+
void add_constant(std::string name, t_const* constant) {
if (constants_.find(name) != constants_.end()) {
throw "Enum " + name + " is already defined!";
@@ -67,6 +80,15 @@
t_const* get_constant(std::string name) { return constants_[name]; }
+ const t_const* get_constant(std::string name) const {
+ const auto it = constants_.find(name);
+ if (constants_.end() != it)
+ {
+ return it->second;
+ }
+ return nullptr;
+ }
+
void print() {
std::map<std::string, t_type*>::iterator iter;
for (iter = types_.begin(); iter != types_.end(); ++iter) {
@@ -95,12 +117,12 @@
resolve_const_value((*v_iter), ((t_set*)ttype)->get_elem_type());
}
} else if (ttype->is_struct()) {
- t_struct* tstruct = (t_struct*)ttype;
+ auto* tstruct = (t_struct*)ttype;
const std::map<t_const_value*, t_const_value*, t_const_value::value_compare>& map = const_val->get_map();
std::map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
for (v_iter = map.begin(); v_iter != map.end(); ++v_iter) {
t_field* field = tstruct->get_field_by_name(v_iter->first->get_string());
- if (field == NULL) {
+ if (field == nullptr) {
throw "No field named \"" + v_iter->first->get_string()
+ "\" was found in struct of type \"" + tstruct->get_name() + "\"";
}
@@ -111,7 +133,7 @@
const_val->set_enum((t_enum*)ttype);
} else {
t_const* constant = get_constant(const_val->get_identifier());
- if (constant == NULL) {
+ if (constant == nullptr) {
throw "No enum value or constant found named \"" + const_val->get_identifier() + "\"!";
}
@@ -157,9 +179,9 @@
} else if (ttype->is_enum()) {
// enum constant with non-identifier value. set the enum and find the
// value's name.
- t_enum* tenum = (t_enum*)ttype;
+ auto* tenum = (t_enum*)ttype;
t_enum_value* enum_value = tenum->get_constant_by_value(const_val->get_integer());
- if (enum_value == NULL) {
+ if (enum_value == nullptr) {
std::ostringstream valstm;
valstm << const_val->get_integer();
throw "Couldn't find a named value in enum " + tenum->get_name() + " for value "
@@ -179,10 +201,6 @@
// Map of names to services
std::map<std::string, t_service*> services_;
-
- // to list map entries
- template <typename From, typename To>
- friend void plugin_output::convert(From*, To&);
};
#endif
diff --git a/compiler/cpp/src/thrift/parse/t_service.h b/compiler/cpp/src/thrift/parse/t_service.h
index e2204ca..a43a515 100644
--- a/compiler/cpp/src/thrift/parse/t_service.h
+++ b/compiler/cpp/src/thrift/parse/t_service.h
@@ -31,9 +31,9 @@
*/
class t_service : public t_type {
public:
- t_service(t_program* program) : t_type(program), extends_(NULL) {}
+ t_service(t_program* program) : t_type(program), extends_(nullptr) {}
- bool is_service() const { return true; }
+ bool is_service() const override { return true; }
void set_extends(t_service* extends) { extends_ = extends; }
diff --git a/compiler/cpp/src/thrift/parse/t_set.h b/compiler/cpp/src/thrift/parse/t_set.h
index f913be4..c0d4a35 100644
--- a/compiler/cpp/src/thrift/parse/t_set.h
+++ b/compiler/cpp/src/thrift/parse/t_set.h
@@ -30,9 +30,11 @@
public:
t_set(t_type* elem_type) : elem_type_(elem_type) {}
- t_type* get_elem_type() const { return elem_type_; }
+ const t_type* get_elem_type() const { return elem_type_; }
- bool is_set() const { return true; }
+ t_type* get_elem_type() { return elem_type_; }
+
+ bool is_set() const override { return true; }
private:
t_type* elem_type_;
diff --git a/compiler/cpp/src/thrift/parse/t_struct.h b/compiler/cpp/src/thrift/parse/t_struct.h
index 4102da7..7e1e6ca 100644
--- a/compiler/cpp/src/thrift/parse/t_struct.h
+++ b/compiler/cpp/src/thrift/parse/t_struct.h
@@ -56,7 +56,7 @@
members_with_value(0),
xsd_all_(false) {}
- void set_name(const std::string& name) {
+ void set_name(const std::string& name) override {
name_ = name;
validate_union_members();
}
@@ -80,7 +80,7 @@
}
// unions may have up to one member defaulted, but not more
- if (field->get_value() != NULL) {
+ if (field->get_value() != nullptr) {
if (1 < ++members_with_value) {
throw "Error: Field " + field->get_name() + " provides another default value for union "
+ name_;
@@ -118,7 +118,7 @@
return false;
}
// returns false when there is a conflict of field names
- if (get_field_by_name(elem->get_name()) != NULL) {
+ if (get_field_by_name(elem->get_name()) != nullptr) {
return false;
}
members_.push_back(elem);
@@ -129,22 +129,16 @@
const members_type& get_members() const { return members_; }
- const members_type& get_sorted_members() { return members_in_id_order_; }
+ const members_type& get_sorted_members() const { return members_in_id_order_; }
- bool is_struct() const { return !is_xception_; }
+ bool is_struct() const override { return !is_xception_; }
- bool is_xception() const { return is_xception_; }
+ bool is_xception() const override { return is_xception_; }
bool is_union() const { return is_union_; }
t_field* get_field_by_name(std::string field_name) {
- members_type::const_iterator m_iter;
- for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) {
- if ((*m_iter)->get_name() == field_name) {
- return *m_iter;
- }
- }
- return NULL;
+ return const_cast<t_field*>(const_cast<const t_struct&>(*this).get_field_by_name(field_name));
}
const t_field* get_field_by_name(std::string field_name) const {
@@ -154,7 +148,7 @@
return *m_iter;
}
}
- return NULL;
+ return nullptr;
}
private:
diff --git a/compiler/cpp/src/thrift/parse/t_type.h b/compiler/cpp/src/thrift/parse/t_type.h
index 3a6d1e0..63f99ed 100644
--- a/compiler/cpp/src/thrift/parse/t_type.h
+++ b/compiler/cpp/src/thrift/parse/t_type.h
@@ -38,7 +38,7 @@
*/
class t_type : public t_doc {
public:
- virtual ~t_type() {}
+ ~t_type() override = default;
virtual void set_name(const std::string& name) { name_ = name; }
@@ -85,13 +85,13 @@
std::map<std::string, std::string> annotations_;
protected:
- t_type() : program_(NULL) { ; }
+ t_type() : program_(nullptr) { ; }
t_type(t_program* program) : program_(program) { ; }
t_type(t_program* program, std::string name) : program_(program), name_(name) { ; }
- t_type(std::string name) : program_(NULL), name_(name) { ; }
+ t_type(std::string name) : program_(nullptr), name_(name) { ; }
t_program* program_;
std::string name_;
diff --git a/compiler/cpp/src/thrift/parse/t_typedef.cc b/compiler/cpp/src/thrift/parse/t_typedef.cc
index 99ffdb8..c808685 100644
--- a/compiler/cpp/src/thrift/parse/t_typedef.cc
+++ b/compiler/cpp/src/thrift/parse/t_typedef.cc
@@ -21,9 +21,13 @@
#include "thrift/parse/t_typedef.h"
#include "thrift/parse/t_program.h"
-t_type* t_typedef::get_type() const {
+t_type* t_typedef::get_type() {
+ return const_cast<t_type*>(const_cast<const t_typedef*>(this)->get_type());
+}
+
+const t_type* t_typedef::get_type() const {
if (type_ == NULL) {
- t_type* type = get_program()->scope()->get_type(symbolic_);
+ const t_type* type = get_program()->scope()->get_type(symbolic_);
if (type == NULL) {
printf("Type \"%s\" not defined\n", symbolic_.c_str());
exit(1);
diff --git a/compiler/cpp/src/thrift/parse/t_typedef.h b/compiler/cpp/src/thrift/parse/t_typedef.h
index aad3a50..d21d863 100644
--- a/compiler/cpp/src/thrift/parse/t_typedef.h
+++ b/compiler/cpp/src/thrift/parse/t_typedef.h
@@ -42,20 +42,22 @@
*/
t_typedef(t_program* program, const std::string& symbolic, bool forward)
: t_type(program, symbolic),
- type_(NULL),
+ type_(nullptr),
symbolic_(symbolic),
forward_(forward)
{}
- ~t_typedef() {}
+ ~t_typedef() override = default;
- t_type* get_type() const;
+ t_type* get_type();
+
+ const t_type* get_type() const;
const std::string& get_symbolic() const { return symbolic_; }
bool is_forward_typedef() const { return forward_; }
- bool is_typedef() const { return true; }
+ bool is_typedef() const override { return true; }
private:
t_type* type_;
diff --git a/compiler/cpp/src/thrift/plugin/Makefile.am b/compiler/cpp/src/thrift/plugin/Makefile.am
deleted file mode 100644
index e84cdbd..0000000
--- a/compiler/cpp/src/thrift/plugin/Makefile.am
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# 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.
-#
-#
-# Contains some contributions under the Thrift Software License.
-# Please see doc/old-thrift-license.txt in the Thrift distribution for
-# details.
-
-AUTOMAKE_OPTIONS = subdir-objects
-
-if WITH_PLUGIN
-plugin_gen = plugin_types.h \
- plugin_types.cpp \
- plugin_constants.h \
- plugin_constants.cpp
-
-BUILT_SOURCES = $(plugin_gen)
-gen.stamp: plugin.thrift $(top_builddir)/compiler/cpp/src/thrift/thrift-bootstrap
- @$(RM) -f gen.tmp
- @touch gen.tmp
- $(top_builddir)/compiler/cpp/src/thrift/thrift-bootstrap -gen cpp -out . $<
- @mv -f gen.tmp $@
-
-$(plugin_gen): gen.stamp
- @if test -f $@; then :; else \
- $(RM) -f gen.stamp; \
- $(MAKE) $(AM_MAKEFLAGS) gen.stamp; \
- fi
-
-clean-local:
- $(RM) version.h windows/version.h $(plugin_gen)
-endif
diff --git a/compiler/cpp/src/thrift/plugin/plugin.cc b/compiler/cpp/src/thrift/plugin/plugin.cc
deleted file mode 100644
index ca5d287..0000000
--- a/compiler/cpp/src/thrift/plugin/plugin.cc
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * 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.
- */
-
-#include "thrift/plugin/plugin.h"
-
-#ifdef _WIN32
-#include <fcntl.h>
-#include <io.h>
-#endif
-
-#include <cassert>
-#include <iostream>
-
-#include <boost/range/adaptor/map.hpp>
-#include <boost/range/algorithm/for_each.hpp>
-
-#include "thrift/generate/t_generator.h"
-#include "thrift/plugin/type_util.h"
-#include "thrift/protocol/TBinaryProtocol.h"
-#include "thrift/transport/TBufferTransports.h"
-#include "thrift/transport/TFDTransport.h"
-#include "thrift/stdcxx.h"
-#include "thrift/plugin/plugin_types.h"
-
-namespace apache {
-namespace thrift {
-namespace plugin {
-
-using apache::thrift::protocol::TBinaryProtocol;
-using apache::thrift::transport::TFDTransport;
-using apache::thrift::transport::TFramedTransport;
-
-#define THRIFT_CONVERT_FORWARD(from_type) \
- template <> \
- typename ToType<from_type>::type* convert_forward<from_type>(const from_type& from)
-
-#define THRIFT_CONVERT_COMPLETE_DECL(from_type) \
- template <> \
- void convert(const from_type& from, ToType<from_type>::type* to)
-
-#define THRIFT_CONVERT_UNARY_DECL(from_type) \
- template <> \
- typename ToType<from_type>::type* convert<from_type>(const from_type& from)
-
-#define THRIFT_CONVERSION_DECL(from_type) \
- THRIFT_CONVERT_FORWARD(from_type); \
- THRIFT_CONVERT_COMPLETE_DECL(from_type); \
- THRIFT_CONVERT_UNARY_DECL(from_type)
-
-#define THRIFT_CONVERT_COMPLETE(from_type) \
- THRIFT_CONVERSION_DECL(from_type) { \
- ToType<from_type>::type* to = convert_forward(from); \
- convert(from, to); \
- return to; \
- } \
- THRIFT_CONVERT_COMPLETE_DECL(from_type)
-
-#define THRIFT_CONVERSION(from_type, ...) \
- THRIFT_CONVERT_FORWARD(from_type) { \
- (void)from; \
- return new ToType<from_type>::type(__VA_ARGS__); \
- } \
- THRIFT_CONVERT_COMPLETE(from_type)
-
-#define THRIFT_ASSIGN_DOC() \
- do { \
- if (from.__isset.doc) \
- to->set_doc(from.doc); \
- } while (0)
-
-#define THRIFT_ASSIGN_ANNOTATIONS() \
- THRIFT_ASSIGN_DOC(); \
- do { \
- if (from.__isset.annotations) \
- to->annotations_ = from.annotations; \
- } while (0)
-
-#define THRIFT_ASSIGN_METADATA() \
- do { \
- to->set_name(from.metadata.name); \
- if (from.metadata.__isset.doc) \
- to->set_doc(from.metadata.doc); \
- if (from.metadata.__isset.annotations) \
- to->annotations_ = from.metadata.annotations; \
- } while (0)
-
-::t_program* g_program = 0;
-
-template <typename C, typename S>
-struct TypeCache {
- C* operator[](const int64_t& k) {
- typename std::map<int64_t, C*>::iterator it = cache.find(k);
- if (it != cache.end()) {
- return it->second;
- } else {
- typename std::map<int64_t, S>::const_iterator cit = source->find(k);
- if (cit == source->end()) {
- throw ThriftPluginError("Type not found");
- }
- return (cache)[k] = convert_forward(cit->second);
- }
- }
-
- void compileAll() {
- boost::for_each(*source | boost::adaptors::map_keys,
- stdcxx::bind(&TypeCache::compile, this, stdcxx::placeholders::_1));
- }
-
- std::map<int64_t, S> const* source;
-
- void clear() {
- source = nullptr ;
- cache.clear() ;
- }
-
-protected:
- std::map<int64_t, C*> cache;
-
-private:
- void compile(const int64_t& k) {
- typename std::map<int64_t, S>::const_iterator cit = source->find(k);
- if (cit == source->end()) {
- throw ThriftPluginError("Type not found ");
- }
- convert(cit->second, (*this)[k]);
- }
-};
-std::map<int64_t, ::t_program*> g_program_cache;
-TypeCache< ::t_type, t_type> g_type_cache;
-TypeCache< ::t_const, t_const> g_const_cache;
-TypeCache< ::t_service, t_service> g_service_cache;
-
-void clear_global_cache() {
- g_type_cache.clear();
- g_const_cache.clear();
- g_service_cache.clear();
-}
-
-void set_global_cache(const TypeRegistry& from) {
- g_type_cache.source = &from.types;
- g_const_cache.source = &from.constants;
- g_service_cache.source = &from.services;
-
- g_type_cache.compileAll();
- g_const_cache.compileAll();
- g_service_cache.compileAll();
-}
-
-template <typename T>
-T* resolve_type(int64_t name) {
- return reinterpret_cast<T*>(g_type_cache[name]);
-}
-
-::t_const* resolve_const(int64_t name) {
- return g_const_cache[name];
-}
-
-::t_service* resolve_service(int64_t name) {
- return g_service_cache[name];
-}
-
-THRIFT_CONVERT_FORWARD(t_base_type) {
-#define T_BASETYPE_CASE(type) \
- case t_base::TYPE_##type: \
- t = ::t_base_type::TYPE_##type; \
- break
-
- ::t_base_type::t_base t = ::t_base_type::TYPE_VOID;
- bool is_binary = false;
- switch (from.value) {
- T_BASETYPE_CASE(VOID);
- T_BASETYPE_CASE(STRING);
- T_BASETYPE_CASE(BOOL);
- T_BASETYPE_CASE(I8);
- T_BASETYPE_CASE(I16);
- T_BASETYPE_CASE(I32);
- T_BASETYPE_CASE(I64);
- T_BASETYPE_CASE(DOUBLE);
- case t_base::TYPE_BINARY:
- t = ::t_base_type::TYPE_STRING;
- is_binary = true;
- break;
- }
- ::t_base_type* to = new ::t_base_type(from.metadata.name, t);
- to->set_binary(is_binary);
- return to;
-#undef T_BASETYPE_CASE
-}
-THRIFT_CONVERT_COMPLETE(t_base_type) {
- THRIFT_ASSIGN_METADATA();
-}
-
-THRIFT_CONVERT_FORWARD(t_typedef) {
- ::t_typedef* to;
- if (from.forward) {
- to = new ::t_typedef(g_program_cache[from.metadata.program_id], from.symbolic, true);
- } else {
- to = new ::t_typedef(g_program_cache[from.metadata.program_id],
- resolve_type< ::t_type>(from.type), from.symbolic);
- }
- return to;
-}
-THRIFT_CONVERT_COMPLETE(t_typedef) {
- THRIFT_ASSIGN_METADATA();
-}
-THRIFT_CONVERSION(t_enum_value, from.name, from.value) {
- assert(to);
- THRIFT_ASSIGN_ANNOTATIONS();
-}
-THRIFT_CONVERSION(t_enum, g_program_cache[from.metadata.program_id]) {
- assert(to);
- THRIFT_ASSIGN_METADATA();
- boost::for_each(from.constants | boost::adaptors::transformed(convert<t_enum_value>),
- stdcxx::bind(&::t_enum::append, to, stdcxx::placeholders::_1));
-}
-THRIFT_CONVERSION(t_list, resolve_type< ::t_type>(from.elem_type)) {
- assert(to);
- THRIFT_ASSIGN_METADATA();
- if (from.__isset.cpp_name)
- to->set_cpp_name(from.cpp_name);
-}
-THRIFT_CONVERSION(t_set, resolve_type< ::t_type>(from.elem_type)) {
- assert(to);
- THRIFT_ASSIGN_METADATA();
- if (from.__isset.cpp_name)
- to->set_cpp_name(from.cpp_name);
-}
-THRIFT_CONVERSION(t_map,
- resolve_type< ::t_type>(from.key_type),
- resolve_type< ::t_type>(from.val_type)) {
- assert(to);
- THRIFT_ASSIGN_METADATA();
- if (from.__isset.cpp_name)
- to->set_cpp_name(from.cpp_name);
-}
-THRIFT_CONVERSION(t_const_value, ) {
-#define T_CONST_VALUE_CASE(type) \
- if (from.__isset.type##_val) \
- to->set_##type(from.type##_val)
-
- assert(to);
- if (from.__isset.map_val) {
- to->set_map();
- for (std::map<t_const_value, t_const_value>::const_iterator it = from.map_val.begin();
- it != from.map_val.end(); it++) {
- to->add_map(convert(it->first), convert(it->second));
- }
- } else if (from.__isset.list_val) {
- to->set_list();
- boost::for_each(from.list_val | boost::adaptors::transformed(&convert<t_const_value>),
- stdcxx::bind(&::t_const_value::add_list, to, stdcxx::placeholders::_1));
- } else
- T_CONST_VALUE_CASE(string);
- else T_CONST_VALUE_CASE(integer);
- else T_CONST_VALUE_CASE(double);
- else if (from.__isset.const_identifier_val) {
- to->set_identifier(from.const_identifier_val.identifier_val) ;
- to->set_enum(resolve_type< ::t_enum>(from.const_identifier_val.enum_val)) ;
- }
-
-#undef T_CONST_VALUE_CASE
-}
-THRIFT_CONVERSION(t_field, resolve_type< ::t_type>(from.type), from.name, from.key) {
- assert(to);
- THRIFT_ASSIGN_ANNOTATIONS();
- to->set_reference(from.reference);
- to->set_req(static_cast< ::t_field::e_req>(from.req));
- if (from.__isset.value) {
- to->set_value(convert(from.value));
- }
-}
-THRIFT_CONVERSION(t_struct, g_program_cache[from.metadata.program_id]) {
- assert(to);
- THRIFT_ASSIGN_METADATA();
- to->set_union(from.is_union);
- to->set_xception(from.is_xception);
- boost::for_each(from.members | boost::adaptors::transformed(convert<t_field>),
- stdcxx::bind(&::t_struct::append, to, stdcxx::placeholders::_1));
-}
-THRIFT_CONVERSION(t_const,
- resolve_type< ::t_type>(from.type),
- from.name,
- convert<t_const_value>(from.value)) {
- assert(to);
- THRIFT_ASSIGN_DOC();
-}
-
-THRIFT_CONVERSION(t_function,
- resolve_type< ::t_type>(from.returntype),
- from.name,
- resolve_type< ::t_struct>(from.arglist),
- resolve_type< ::t_struct>(from.xceptions),
- from.is_oneway) {
- assert(to);
- THRIFT_ASSIGN_DOC();
-}
-
-THRIFT_CONVERSION(t_service, g_program_cache[from.metadata.program_id]) {
- assert(to);
- assert(from.metadata.program_id);
- assert(g_program_cache[from.metadata.program_id]);
- THRIFT_ASSIGN_METADATA();
-
- boost::for_each(from.functions | boost::adaptors::transformed(convert<t_function>),
- stdcxx::bind(&::t_service::add_function, to, stdcxx::placeholders::_1));
-
- if (from.__isset.extends_)
- to->set_extends(resolve_service(from.extends_));
-}
-
-THRIFT_CONVERT_FORWARD(t_type) {
-#define T_TYPE_CASE_FW_T(case, type) \
- if (from.__isset.case##_val) \
- return convert_forward<type>(from.case##_val)
-#define T_TYPE_CASE_FW(case) T_TYPE_CASE_FW_T(case, t_##case)
-
- T_TYPE_CASE_FW(base_type);
- T_TYPE_CASE_FW(typedef);
- T_TYPE_CASE_FW(enum);
- T_TYPE_CASE_FW(struct);
- T_TYPE_CASE_FW_T(xception, t_struct);
- T_TYPE_CASE_FW(list);
- T_TYPE_CASE_FW(set);
- T_TYPE_CASE_FW(map);
- T_TYPE_CASE_FW(service);
- throw ThriftPluginError("Invalid data: Type union has no value.");
-#undef T_TYPE_CASE_FW_T
-#undef T_TYPE_CASE_FW
-}
-THRIFT_CONVERT_COMPLETE(t_type) {
-#define T_TYPE_CASE_T(case, type) \
- else if (from.__isset.case##_val) \
- convert<type, ::type>(from.case##_val, reinterpret_cast< ::type*>(to))
-#define T_TYPE_CASE(case) T_TYPE_CASE_T(case, t_##case)
-
- if (false) {
- }
- T_TYPE_CASE(base_type);
- T_TYPE_CASE(typedef);
- T_TYPE_CASE(enum);
- T_TYPE_CASE(struct);
- T_TYPE_CASE_T(xception, t_struct);
- T_TYPE_CASE(list);
- T_TYPE_CASE(set);
- T_TYPE_CASE(map);
- T_TYPE_CASE(service);
- else {
- throw ThriftPluginError("Invalid data: Type union has no value.");
- }
-#undef T_TYPE_CASE_T
-#undef T_TYPE_CASE
-}
-
-THRIFT_CONVERSION(t_scope, ) {
- assert(to);
-#define T_SCOPE_RESOLVE(type, name, a) \
- for (std::vector<int64_t>::const_iterator it = from.name##s.begin(); it != from.name##s.end(); \
- it++) { \
- ::t_##type* t = resolve_##type a(*it); \
- to->add_##name(t->get_name(), t); \
- }
- T_SCOPE_RESOLVE(type, type, < ::t_type>);
- T_SCOPE_RESOLVE(const, constant, );
- T_SCOPE_RESOLVE(service, service, );
-#undef T_SCOPE_RESOLVE
-}
-
-THRIFT_CONVERT_FORWARD(t_program) {
- ::t_program* to = new ::t_program(from.path, from.name);
- for (std::vector<t_program>::const_iterator it = from.includes.begin(); it != from.includes.end();
- it++) {
- to->add_include(convert_forward(*it));
- }
- g_program_cache[from.program_id] = to;
- return to;
-}
-THRIFT_CONVERT_COMPLETE(t_program) {
- assert(to);
- g_program = to;
- convert<t_scope, ::t_scope>(from.scope, to->scope());
- THRIFT_ASSIGN_DOC();
-
- to->set_out_path(from.out_path, from.out_path_is_absolute);
-
- boost::for_each(from.typedefs | boost::adaptors::transformed(&resolve_type< ::t_typedef>),
- stdcxx::bind(&::t_program::add_typedef, to, stdcxx::placeholders::_1));
- boost::for_each(from.enums | boost::adaptors::transformed(&resolve_type< ::t_enum>),
- stdcxx::bind(&::t_program::add_enum, to, stdcxx::placeholders::_1));
- for (std::vector<int64_t>::const_iterator it = from.objects.begin(); it != from.objects.end();
- it++) {
- ::t_struct* t2 = resolve_type< ::t_struct>(*it);
- if (t2->is_xception()) {
- to->add_xception(t2);
- } else {
- to->add_struct(t2);
- }
- }
- boost::for_each(from.consts | boost::adaptors::transformed(&resolve_const),
- stdcxx::bind(&::t_program::add_const, to, stdcxx::placeholders::_1));
- boost::for_each(from.services | boost::adaptors::transformed(&resolve_service),
- stdcxx::bind(&::t_program::add_service, to, stdcxx::placeholders::_1));
-
- for (std::vector<t_program>::const_iterator it = from.includes.begin(); it != from.includes.end();
- it++) {
- convert(*it, g_program_cache[it->program_id]);
- }
- std::for_each(from.c_includes.begin(), from.c_includes.end(),
- stdcxx::bind(&::t_program::add_c_include, to, stdcxx::placeholders::_1));
- std::for_each(from.cpp_includes.begin(), from.cpp_includes.end(),
- stdcxx::bind(&::t_program::add_cpp_include, to, stdcxx::placeholders::_1));
- for (std::map<std::string, std::string>::const_iterator it = from.namespaces.begin();
- it != from.namespaces.end(); it++) {
- to->set_namespace(it->first, it->second);
- }
-
- to->set_include_prefix(from.include_prefix);
- to->set_namespace(from.namespace_);
-}
-
-int GeneratorPlugin::exec(int, char* []) {
-#ifdef _WIN32
- _setmode(fileno(stdin), _O_BINARY);
-#endif
- stdcxx::shared_ptr<TFramedTransport> transport(
- new TFramedTransport(stdcxx::make_shared<TFDTransport>(fileno(stdin))));
- TBinaryProtocol proto(transport);
- GeneratorInput input;
- try {
- input.read(&proto);
- } catch (std::exception& err) {
- std::cerr << "Error while receiving plugin data: " << err.what() << std::endl;
- return -1;
- }
- initGlobals();
- ::t_program* p = g_program = convert_forward(input.program);
- set_global_cache(input.type_registry);
- convert(input.program, p);
-
- int ret = generate(p, input.parsed_options);
- clearGlobals();
-
- return ret;
-}
-
-::t_const_value::t_const_value_type const_value_case(const t_const_value& v) {
- if (v.__isset.map_val)
- return ::t_const_value::CV_MAP;
- if (v.__isset.list_val)
- return ::t_const_value::CV_LIST;
- if (v.__isset.string_val)
- return ::t_const_value::CV_STRING;
- if (v.__isset.integer_val)
- return ::t_const_value::CV_INTEGER;
- if (v.__isset.double_val)
- return ::t_const_value::CV_DOUBLE;
- if (v.__isset.const_identifier_val)
- return ::t_const_value::CV_IDENTIFIER;
- throw ThriftPluginError("Unknown const value type");
-}
-
-bool t_const_value::operator<(const t_const_value& that) const {
- ::t_const_value::t_const_value_type t1 = const_value_case(*this);
- ::t_const_value::t_const_value_type t2 = const_value_case(that);
- if (t1 != t2)
- return t1 < t2;
- switch (t1) {
- case ::t_const_value::CV_INTEGER:
- return integer_val < that.integer_val;
- case ::t_const_value::CV_DOUBLE:
- return double_val < that.double_val;
- case ::t_const_value::CV_STRING:
- return string_val < that.string_val;
- case ::t_const_value::CV_MAP:
- if (that.map_val.empty())
- return false;
- else if (map_val.empty())
- return true;
- else
- return map_val.begin()->first < that.map_val.begin()->first;
- case ::t_const_value::CV_LIST:
- if (that.list_val.empty())
- return false;
- else if (list_val.empty())
- return true;
- else
- return list_val.front() < that.list_val.front();
- case ::t_const_value::CV_IDENTIFIER:
- return integer_val < that.integer_val;
- }
- throw ThriftPluginError("Unknown const value type");
-}
-}
-}
-}
diff --git a/compiler/cpp/src/thrift/plugin/plugin.h b/compiler/cpp/src/thrift/plugin/plugin.h
deleted file mode 100644
index 705cd41..0000000
--- a/compiler/cpp/src/thrift/plugin/plugin.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef T_PLUGIN_PLUGIN_H
-#define T_PLUGIN_PLUGIN_H
-
-#include "thrift/Thrift.h"
-
-class t_program;
-
-namespace apache {
-namespace thrift {
-namespace plugin {
-
-struct ThriftPluginError : public apache::thrift::TException {
- ThriftPluginError(const std::string& msg) : apache::thrift::TException(msg) {}
-};
-
-class GeneratorPlugin {
-public:
- int exec(int argc, char* argv[]);
- virtual int generate(::t_program*, const std::map<std::string, std::string>&) = 0;
-};
-}
-}
-}
-
-#endif
diff --git a/compiler/cpp/src/thrift/plugin/plugin.thrift b/compiler/cpp/src/thrift/plugin/plugin.thrift
deleted file mode 100644
index 6d98f99..0000000
--- a/compiler/cpp/src/thrift/plugin/plugin.thrift
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * 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.
- */
-
-namespace as3 org.apache.thrift.plugin
-namespace cpp apache.thrift.plugin
-namespace csharp Thrift.Plugin
-namespace d thrift.plugin
-namespace delphi Thrift.Plugin
-namespace erl thrift.plugin
-namespace go thrift
-namespace haxe org.apache.thrift.plugin
-namespace hs Thrift.Plugin
-namespace java org.apache.thrift.plugin
-namespace ocaml Thrift
-namespace perl Thrift.Plugin
-namespace php thrift.plugin
-namespace py thrift.plugin
-namespace rb Thrift
-
-typedef i64 t_program_id
-typedef i64 t_type_id
-typedef i64 t_const_id
-typedef i64 t_service_id
-
-enum t_base {
- TYPE_VOID
- TYPE_STRING
- TYPE_BOOL
- TYPE_I8
- TYPE_I16
- TYPE_I32
- TYPE_I64
- TYPE_DOUBLE
- TYPE_BINARY
-}
-
-struct TypeMetadata {
- 1: required string name
- 2: required t_program_id program_id
- 99: optional map<string, string> annotations
- 100: optional string doc
-}
-
-struct t_base_type {
- 1: required TypeMetadata metadata
- 2: required t_base value
-}
-
-struct t_list {
- 1: required TypeMetadata metadata
- 2: optional string cpp_name
- 3: required t_type_id elem_type
-}
-
-struct t_set {
- 1: required TypeMetadata metadata
- 2: optional string cpp_name
- 3: required t_type_id elem_type
-}
-
-struct t_map {
- 1: required TypeMetadata metadata
- 2: optional string cpp_name
- 3: required t_type_id key_type
- 4: required t_type_id val_type
-}
-
-struct t_typedef {
- 1: required TypeMetadata metadata
- 2: required t_type_id type
- 3: required string symbolic
- 4: required bool forward
-}
-
-struct t_enum_value {
- 1: required string name
- 2: required i32 value
- 99: optional map<string, string> annotations
- 100: optional string doc
-}
-struct t_enum {
- 1: required TypeMetadata metadata
- 2: required list<t_enum_value> constants
-}
-
-enum Requiredness {
- T_REQUIRED = 0
- T_OPTIONAL = 1
- T_OPT_IN_REQ_OUT = 2
-}
-
-struct t_const_identifier_value {
- 1: required string identifier_val
- 2: required t_type_id enum_val
-}
-
-union t_const_value {
- 1: optional map<t_const_value, t_const_value> map_val
- 2: optional list<t_const_value> list_val
- 3: optional string string_val
- 4: optional i64 integer_val
- 5: optional double double_val
- 8: optional t_const_identifier_value const_identifier_val
-}
-
-struct t_const {
- 1: required string name
- 2: required t_type_id type
- 3: required t_const_value value
- 100: optional string doc
-}
-struct t_field {
- 1: required string name
- 2: required t_type_id type
- 3: required i32 key
- 4: required Requiredness req
- 5: optional t_const_value value
- 10: required bool reference
- 99: optional map<string, string> annotations
- 100: optional string doc
-}
-struct t_struct {
- 1: required TypeMetadata metadata
- 2: required list<t_field> members
- 3: required bool is_union
- 4: required bool is_xception
-}
-struct t_function {
- 1: required string name
- 2: required t_type_id returntype
- 3: required t_type_id arglist
- 4: required t_type_id xceptions
- 5: required bool is_oneway
- 100: optional string doc
-}
-struct t_service {
- 1: required TypeMetadata metadata
- 2: required list<t_function> functions
- 3: optional t_service_id extends_
-}
-union t_type {
- 1: optional t_base_type base_type_val
- 2: optional t_typedef typedef_val
- 3: optional t_enum enum_val
- 4: optional t_struct struct_val
- 5: optional t_struct xception_val
- 6: optional t_list list_val
- 7: optional t_set set_val
- 8: optional t_map map_val
- 9: optional t_service service_val
-}
-struct t_scope {
- 1: required list<t_type_id> types
- 2: required list<t_const_id> constants
- 3: required list<t_service_id> services
-}
-
-struct TypeRegistry {
- 1: required map<t_type_id, t_type> types
- 2: required map<t_const_id, t_const> constants
- 3: required map<t_service_id, t_service> services
-}
-
-struct t_program {
- 1: required string name
- 2: required t_program_id program_id
- 3: required string path
- 4: required string namespace_
- 5: required string out_path
- 6: required bool out_path_is_absolute
- 8: required list<t_program> includes
- 9: required string include_prefix
- 10: required t_scope scope
-
- 11: required list<t_type_id> typedefs
- 12: required list<t_type_id> enums
- 13: required list<t_const_id> consts
- 14: required list<t_type_id> objects
- 15: required list<t_service_id> services
-
- 16: required map<string, string> namespaces
- 17: required list<string> cpp_includes
- 18: required list<string> c_includes
- 100: optional string doc
-}
-
-struct GeneratorInput {
- 1: required t_program program
- 2: required TypeRegistry type_registry
- 3: required map<string, string> parsed_options
-}
diff --git a/compiler/cpp/src/thrift/plugin/plugin_output.cc b/compiler/cpp/src/thrift/plugin/plugin_output.cc
deleted file mode 100644
index 81b9a2a..0000000
--- a/compiler/cpp/src/thrift/plugin/plugin_output.cc
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * 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.
- */
-
-#ifdef _WIN32
-#include <cstdio>
-#include <fcntl.h>
-#include <io.h>
-#include <iostream>
-#define THRIFT_POPEN(cmd) _popen(cmd, "wb")
-#define THRIFT_PCLOSE _pclose
-#else
-#define THRIFT_POPEN(cmd) popen(cmd, "w")
-#define THRIFT_PCLOSE pclose
-#endif
-
-#include "thrift/plugin/plugin_output.h"
-
-#include <boost/range/adaptor/map.hpp>
-#include <boost/range/algorithm/copy.hpp>
-#include <boost/range/algorithm/transform.hpp>
-
-#include "thrift/generate/t_generator.h"
-#include "thrift/plugin/plugin.h"
-#include "thrift/plugin/type_util.h"
-#include "thrift/protocol/TBinaryProtocol.h"
-#include "thrift/stdcxx.h"
-#include "thrift/transport/TBufferTransports.h"
-#include "thrift/transport/TFDTransport.h"
-
-#include "thrift/plugin/plugin_types.h"
-
-namespace plugin_output {
-
-template <typename From>
-typename apache::thrift::plugin::ToType<From>::type convert(From* from) {
- typename apache::thrift::plugin::ToType<From>::type to;
- convert(from, to);
- return to;
-}
-
-using apache::thrift::protocol::TBinaryProtocol;
-using apache::thrift::stdcxx::make_shared;
-using apache::thrift::stdcxx::shared_ptr;
-using apache::thrift::transport::TFDTransport;
-using apache::thrift::transport::TFramedTransport;
-
-using namespace apache::thrift;
-
-#define THRIFT_CONVERSION_N(from_type, to_type) \
- template <> \
- void convert<from_type, to_type>(from_type * from, to_type & to)
-#define THRIFT_CONVERSION(type) THRIFT_CONVERSION_N(::type, plugin::type)
-
-#define THRIFT_ASSIGN_N(from_name, to_name, prefix) \
- do { \
- if (from) \
- to.__set_##to_name(prefix(from->from_name)); \
- } while (0)
-
-#define THRIFT_ASSIGN(name) THRIFT_ASSIGN_N(get_##name(), name, )
-#define THRIFT_ASSIGN_CONVERT(type, from_name, to_name) \
- do { \
- if (from && from->from_name) { \
- to.__set_##to_name(convert(from->from_name)); \
- } \
- } while (0)
-
-#define THRIFT_ASSIGN_OPT(name) \
- do { \
- if (from->has_##name()) \
- THRIFT_ASSIGN(name); \
- } while (0)
-
-#define THRIFT_ASSIGN_LIST_N(type, from_name, to_name) \
- do { \
- if (from && !from->from_name.empty()) { \
- std::transform(from->from_name.begin(), \
- from->from_name.end(), \
- std::back_inserter(to.to_name), \
- convert< ::type>); \
- } \
- } while (0)
-
-#define THRIFT_ASSIGN_METADATA() convert(reinterpret_cast<t_type*>(from), to.metadata)
-
-// a generator of sequential unique identifiers for addresses -- so
-// that the TypeCache below can use those IDs instead of
-// addresses. This allows GeneratorInput's various
-// t_{program,type,etc}_id types to be dense consecutively-numbered
-// integers, instead of large random-seeming integers.
-//
-// Furthermore, this allows GeneratorInput to be deterministic (no
-// addresses, so no pseudo-randomness) and that means reproducibility
-// of output.
-const int64_t ONE_MILLION = 1000 * 1000;
-class id_generator {
-public:
- id_generator() : addr2id_(), next_id_(ONE_MILLION) {}
-
- void clear() {
- addr2id_.clear() ;
- next_id_ = ONE_MILLION ;
- }
-
- int64_t gensym(const int64_t addr) {
- if (!addr) return 0L ;
- std::map<int64_t, int64_t>::iterator it = addr2id_.find(addr);
- if (it != addr2id_.end()) return it->second ;
- int64_t id = next_id_++ ;
- addr2id_.insert(std::make_pair(addr, id)) ;
- return id ;
- }
-
- std::map<int64_t, int64_t> addr2id_ ;
- int64_t next_id_ ;
-} ;
-
-// To avoid multiple instances of same type, t_type, t_const and t_service are stored in one place
-// and referenced by ID.
-template <typename T>
-struct TypeCache {
- typedef typename plugin::ToType<T>::type to_type;
- id_generator idgen ;
- std::map<int64_t, to_type> cache;
-
- template <typename T2>
- int64_t store(T2* t) {
- intptr_t addr = reinterpret_cast<intptr_t>(t);
- if (!addr) return 0L ;
-
- int64_t id = idgen.gensym(addr) ;
- if (cache.end() != cache.find(id)) return id ;
-
- // HACK: fake resolve for recursive type
- cache.insert(std::make_pair(id, to_type()));
- // overwrite with true value
- cache[id] = convert(t);
- return id ;
- }
-
- void clear() { cache.clear() ; idgen.clear(); }
-};
-
-template <typename T>
-int64_t store_type(T* t);
-
-#define T_STORE(type) \
- TypeCache<t_##type> type##_cache; \
- template <> \
- plugin::t_##type##_id store_type<t_##type>(t_##type * t) { \
- return type##_cache.store<t_##type>(t); \
- }
-T_STORE(type)
-T_STORE(const)
-T_STORE(service)
-#undef T_STORE
-// this id_generator is for gensymm-ing t_program_id
-id_generator program_cache ;
-
-#define THRIFT_ASSIGN_ID_N(t, from_name, to_name) \
- do { \
- if (from && from->from_name) \
- to.__set_##to_name(store_type<t>(from->from_name)); \
- } while (0)
-
-#define THRIFT_ASSIGN_ID(name) THRIFT_ASSIGN_ID_N(t_type, get_##name(), name)
-
-#define THRIFT_ASSIGN_LIST_ID(t, name) \
- do { \
- if (from && !from->get_##name##s().empty()) { \
- std::transform(from->get_##name##s().begin(), \
- from->get_##name##s().end(), \
- std::back_inserter(to.name##s), \
- &store_type<t>); \
- } \
- } while (0)
-
-THRIFT_CONVERSION_N(::t_type, plugin::TypeMetadata) {
- to.program_id = program_cache.gensym(reinterpret_cast<int64_t>(from->get_program()));
- THRIFT_ASSIGN_N(annotations_, annotations, );
- if (from->has_doc()) {
- to.__set_doc(from->get_doc());
- }
- THRIFT_ASSIGN(name);
-}
-
-THRIFT_CONVERSION(t_typedef) {
- THRIFT_ASSIGN_METADATA();
- THRIFT_ASSIGN_ID(type);
- THRIFT_ASSIGN(symbolic);
- THRIFT_ASSIGN_N(is_forward_typedef(), forward, );
-}
-
-THRIFT_CONVERSION(t_enum_value) {
- THRIFT_ASSIGN_OPT(doc);
- THRIFT_ASSIGN(name);
- THRIFT_ASSIGN(value);
-}
-
-THRIFT_CONVERSION(t_enum) {
- THRIFT_ASSIGN_METADATA();
- THRIFT_ASSIGN_LIST_N(t_enum_value, get_constants(), constants);
-}
-
-THRIFT_CONVERSION(t_const_value) {
- switch (from->get_type()) {
- case t_const_value::CV_INTEGER:
- THRIFT_ASSIGN_N(get_integer(), integer_val, );
- break;
- case t_const_value::CV_DOUBLE:
- THRIFT_ASSIGN_N(get_double(), double_val, );
- break;
- case t_const_value::CV_STRING:
- THRIFT_ASSIGN_N(get_string(), string_val, );
- break;
- case t_const_value::CV_IDENTIFIER:
- if (from) {
- apache::thrift::plugin::t_const_identifier_value cidval ;
- if (from->enum_)
- cidval.__set_enum_val(store_type<t_type>(from->enum_));
- cidval.__set_identifier_val(from->get_identifier());
- to.__set_const_identifier_val(cidval) ;
- }
- break;
- case t_const_value::CV_MAP:
- to.__isset.map_val = true;
- if (from && !from->get_map().empty()) {
- for (std::map< ::t_const_value*, ::t_const_value*>::const_iterator it
- = from->get_map().begin();
- it != from->get_map().end();
- it++) {
- to.map_val.insert(std::make_pair(convert(it->first), convert(it->second)));
- }
- }
- break;
- case t_const_value::CV_LIST:
- to.__isset.list_val = true;
- THRIFT_ASSIGN_LIST_N(t_const_value, get_list(), list_val);
- break;
- default:
- throw plugin::ThriftPluginError("const value has no value");
- }
-}
-THRIFT_CONVERSION(t_const) {
- THRIFT_ASSIGN_OPT(doc);
- THRIFT_ASSIGN(name);
- THRIFT_ASSIGN_ID(type);
- THRIFT_ASSIGN_CONVERT(t_const_value, get_value(), value);
-}
-THRIFT_CONVERSION(t_field) {
- THRIFT_ASSIGN_OPT(doc);
- THRIFT_ASSIGN(name);
- THRIFT_ASSIGN(key);
- THRIFT_ASSIGN_N(get_req(), req, (plugin::Requiredness::type));
- THRIFT_ASSIGN(reference);
- THRIFT_ASSIGN_ID(type);
- THRIFT_ASSIGN_CONVERT(t_const_value, get_value(), value);
-}
-THRIFT_CONVERSION(t_struct) {
- THRIFT_ASSIGN_METADATA();
- THRIFT_ASSIGN_LIST_N(t_field, get_members(), members);
- THRIFT_ASSIGN_N(is_union(), is_union, );
- THRIFT_ASSIGN_N(is_xception(), is_xception, );
-}
-THRIFT_CONVERSION(t_function) {
- THRIFT_ASSIGN_OPT(doc);
- THRIFT_ASSIGN(name);
- THRIFT_ASSIGN_ID(returntype);
- THRIFT_ASSIGN_N(is_oneway(), is_oneway, );
- THRIFT_ASSIGN_ID(arglist);
- THRIFT_ASSIGN_ID(xceptions);
-}
-
-THRIFT_CONVERSION(t_list) {
- THRIFT_ASSIGN_METADATA();
- THRIFT_ASSIGN_OPT(cpp_name);
- THRIFT_ASSIGN_ID(elem_type);
-}
-THRIFT_CONVERSION(t_set) {
- THRIFT_ASSIGN_METADATA();
- THRIFT_ASSIGN_OPT(cpp_name);
- THRIFT_ASSIGN_ID(elem_type);
-}
-THRIFT_CONVERSION(t_map) {
- THRIFT_ASSIGN_METADATA();
- THRIFT_ASSIGN_OPT(cpp_name);
- THRIFT_ASSIGN_ID(key_type);
- THRIFT_ASSIGN_ID(val_type);
-}
-
-THRIFT_CONVERSION(t_service) {
- THRIFT_ASSIGN_METADATA();
- THRIFT_ASSIGN_LIST_N(t_function, get_functions(), functions);
- THRIFT_ASSIGN_ID_N(t_service, get_extends(), extends_);
-}
-
-THRIFT_CONVERSION(t_base_type) {
- THRIFT_ASSIGN_METADATA();
- if (from->is_binary()) {
- to.value = plugin::t_base::TYPE_BINARY;
- } else {
- switch (from->get_base()) {
-#define T_BASETYPE_CASE(name) \
- case t_base_type::TYPE_##name: \
- to.value = plugin::t_base::TYPE_##name; \
- break
- T_BASETYPE_CASE(VOID);
- T_BASETYPE_CASE(STRING);
- T_BASETYPE_CASE(BOOL);
- T_BASETYPE_CASE(I8);
- T_BASETYPE_CASE(I16);
- T_BASETYPE_CASE(I32);
- T_BASETYPE_CASE(I64);
- T_BASETYPE_CASE(DOUBLE);
- default:
- throw plugin::ThriftPluginError("Base type union has no value");
- break;
-#undef T_BASETYPE_CASE
- }
- }
-}
-THRIFT_CONVERSION(t_type) {
-#define T_CONVERT_UNION_N(name, type) \
- else if (from->is_##name()) { \
- to.__isset.name##_val = true; \
- convert(reinterpret_cast< ::type*>(from), to.name##_val); \
- }
-#define T_CONVERT_UNION(name) T_CONVERT_UNION_N(name, t_##name)
- if (false) {
- }
- T_CONVERT_UNION(base_type)
- T_CONVERT_UNION(typedef)
- T_CONVERT_UNION(enum)
- T_CONVERT_UNION(struct)
- T_CONVERT_UNION_N(xception, t_struct)
- T_CONVERT_UNION(list)
- T_CONVERT_UNION(set)
- T_CONVERT_UNION(map)
- T_CONVERT_UNION(service)
- else {
- throw plugin::ThriftPluginError("Type union has no value");
- }
-#undef T_CONVERT_UNION_N
-#undef T_CONVERT_UNION
-}
-
-THRIFT_CONVERSION(t_scope) {
-#define T_SCOPE_ASSIGN(name, type) \
- boost::copy(from->name##s_ | boost::adaptors::map_values \
- | boost::adaptors::transformed(&store_type<type>), \
- std::back_inserter(to.name##s))
- T_SCOPE_ASSIGN(type, t_type);
- T_SCOPE_ASSIGN(constant, t_const);
- T_SCOPE_ASSIGN(service, t_service);
-#undef T_SCOPE_ASSIGN
-}
-
-void get_global_cache(plugin::TypeRegistry& reg) {
- reg.types = type_cache.cache;
- reg.constants = const_cache.cache;
- reg.services = service_cache.cache;
-}
-
-void clear_global_cache() {
- type_cache.clear();
- const_cache.clear();
- service_cache.clear();
- program_cache.clear() ;
-}
-
-THRIFT_CONVERSION(t_program) {
- THRIFT_ASSIGN_CONVERT(t_scope, scope(), scope);
- THRIFT_ASSIGN(path);
- THRIFT_ASSIGN(out_path);
- THRIFT_ASSIGN(name);
- THRIFT_ASSIGN(include_prefix);
- THRIFT_ASSIGN(cpp_includes);
- THRIFT_ASSIGN(c_includes);
- THRIFT_ASSIGN(namespaces);
- THRIFT_ASSIGN_N(is_out_path_absolute(), out_path_is_absolute, );
- THRIFT_ASSIGN_N(get_namespace(), namespace_, );
- THRIFT_ASSIGN_LIST_ID(t_type, typedef);
- THRIFT_ASSIGN_LIST_ID(t_type, enum);
- THRIFT_ASSIGN_LIST_ID(t_type, object);
- THRIFT_ASSIGN_LIST_ID(t_const, const);
- THRIFT_ASSIGN_LIST_ID(t_service, service);
- THRIFT_ASSIGN_LIST_N(t_program, get_includes(), includes);
- to.program_id = program_cache.gensym(reinterpret_cast<plugin::t_program_id>(from));
-}
-
-PluginDelegateResult delegateToPlugin(t_program* program, const std::string& options) {
- std::string language;
- std::map<std::string, std::string> parsed_options;
- t_generator::parse_options(options, language, parsed_options);
- std::string cmd = "thrift-gen-";
- if (language.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789")
- != std::string::npos) {
- std::cerr << "Invalid language name" << std::endl;
- return PLUGIN_FAILURE;
- }
- cmd.append(language);
- FILE* fd = THRIFT_POPEN(cmd.c_str());
- if (fd) {
-#ifdef _WIN32
- _setmode(fileno(fd), _O_BINARY);
-#endif
- shared_ptr<TFramedTransport> transport(
- new TFramedTransport(make_shared<TFDTransport>(fileno(fd))));
- TBinaryProtocol proto(transport);
-
- plugin::GeneratorInput input;
- input.__set_parsed_options(parsed_options);
- clear_global_cache();
- convert(program, input.program);
- get_global_cache(input.type_registry);
- try {
- input.write(&proto);
- transport->flush();
- } catch (std::exception& err) {
- std::cerr << "Error while sending data to plugin: " << err.what() << std::endl;
- THRIFT_PCLOSE(fd);
- return PLUGIN_FAILURE;
- }
-
- // TODO: be prepared for hang or crash of child process
- int ret = THRIFT_PCLOSE(fd);
- if (!ret) {
- return PLUGIN_SUCCEESS;
- } else {
- std::cerr << "plugin process returned non zero exit code: " << ret << std::endl;
- return PLUGIN_FAILURE;
- }
- }
- clear_global_cache();
- return PLUGIN_NOT_FOUND;
-}
-}
-
diff --git a/compiler/cpp/src/thrift/plugin/type_util.h b/compiler/cpp/src/thrift/plugin/type_util.h
deleted file mode 100644
index 996b5c6..0000000
--- a/compiler/cpp/src/thrift/plugin/type_util.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef T_PLUGIN_TYPE_UTIL_H
-#define T_PLUGIN_TYPE_UTIL_H
-
-namespace apache {
-namespace thrift {
-namespace plugin {
-
-template <typename From>
-struct ToType {};
-
-template <typename From>
-typename ToType<From>::type* convert_forward(const From&);
-
-template <typename From, typename To>
-void convert(const From&, To*);
-
-template <typename From>
-typename ToType<From>::type* convert(const From& from);
-
-class TypeRegistry;
-void set_global_cache(const TypeRegistry&);
-void clear_global_cache();
-}
-}
-}
-
-// conversion from raw compiler types to plugin wire type
-namespace plugin_output {
-
-template <typename From, typename To>
-void convert(From* from, To& to);
-
-template <typename From>
-typename apache::thrift::plugin::ToType<From>::type convert(From* from);
-
-void get_global_cache(apache::thrift::plugin::TypeRegistry&);
-void clear_global_cache();
-}
-
-#define THRIFT_TYPE_MAPPING(TYPE) \
- class TYPE; \
- namespace apache { \
- namespace thrift { \
- namespace plugin { \
- class TYPE; \
- template <> \
- struct ToType< ::TYPE> { \
- typedef TYPE type; \
- }; \
- template <> \
- struct ToType<TYPE> { \
- typedef ::TYPE type; \
- }; \
- } \
- } \
- }
-THRIFT_TYPE_MAPPING(t_base_type)
-THRIFT_TYPE_MAPPING(t_const)
-THRIFT_TYPE_MAPPING(t_const_value)
-THRIFT_TYPE_MAPPING(t_container)
-THRIFT_TYPE_MAPPING(t_doc)
-THRIFT_TYPE_MAPPING(t_enum)
-THRIFT_TYPE_MAPPING(t_enum_value)
-THRIFT_TYPE_MAPPING(t_field)
-THRIFT_TYPE_MAPPING(t_function)
-THRIFT_TYPE_MAPPING(t_list)
-THRIFT_TYPE_MAPPING(t_map)
-THRIFT_TYPE_MAPPING(t_program)
-THRIFT_TYPE_MAPPING(t_scope)
-THRIFT_TYPE_MAPPING(t_service)
-THRIFT_TYPE_MAPPING(t_set)
-THRIFT_TYPE_MAPPING(t_struct)
-THRIFT_TYPE_MAPPING(t_type)
-THRIFT_TYPE_MAPPING(t_typedef)
-#undef THRIFT_TYPE_MAPPING
-#endif
diff --git a/compiler/cpp/src/thrift/thriftl.ll b/compiler/cpp/src/thrift/thriftl.ll
index 4f783be..282e030 100644
--- a/compiler/cpp/src/thrift/thriftl.ll
+++ b/compiler/cpp/src/thrift/thriftl.ll
@@ -207,15 +207,14 @@
"cpp_include" { return tok_cpp_include; }
"cpp_type" { return tok_cpp_type; }
"java_package" { error_unsupported_namespace_decl("java_package", "java"); /* do nothing */ }
-"cocoa_prefix" { error_unsupported_namespace_decl("cocoa_prefix", "cocoa"); /* do nothing */ }
"csharp_namespace" { error_unsupported_namespace_decl("csharp"); /* do nothing */ }
"delphi_namespace" { error_unsupported_namespace_decl("delphi"); /* do nothing */ }
"php_namespace" { error_unsupported_namespace_decl("php"); /* do nothing */ }
"py_module" { error_unsupported_namespace_decl("py_module", "py"); /* do nothing */ }
"perl_package" { error_unsupported_namespace_decl("perl_package", "perl"); /* do nothing */ }
"ruby_namespace" { error_unsupported_namespace_decl("ruby"); /* do nothing */ }
-"smalltalk_category" { error_unsupported_namespace_decl("smalltalk_category", "smalltalk.category"); /* do nothing */ }
-"smalltalk_prefix" { error_unsupported_namespace_decl("smalltalk_category", "smalltalk.category"); /* do nothing */ }
+"smalltalk_category" { error_unsupported_namespace_decl("smalltalk_category", "st"); /* do nothing */ }
+"smalltalk_prefix" { error_unsupported_namespace_decl("smalltalk_prefix", "st"); /* do nothing */ }
"xsd_all" { return tok_xsd_all; }
"xsd_optional" { return tok_xsd_optional; }
"xsd_nillable" { return tok_xsd_nillable; }
diff --git a/compiler/cpp/src/thrift/windows/config.h b/compiler/cpp/src/thrift/windows/config.h
index d2269cf..6ba4f9a 100644
--- a/compiler/cpp/src/thrift/windows/config.h
+++ b/compiler/cpp/src/thrift/windows/config.h
@@ -46,25 +46,6 @@
// squelch bool conversion performance warning
#pragma warning(disable : 4800)
-// MSVC10 (2010) or later has stdint.h
-#if _MSC_VER >= 1600
-#define HAVE_STDINT_H 1
-#endif
-
-// Must be using VS2010 or later, or boost, so that C99 types are defined in the global namespace
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#else
-#include <boost/cstdint.hpp>
-
-typedef boost::int64_t int64_t;
-typedef boost::uint64_t uint64_t;
-typedef boost::int32_t int32_t;
-typedef boost::uint32_t uint32_t;
-typedef boost::int16_t int16_t;
-typedef boost::uint16_t uint16_t;
-typedef boost::int8_t int8_t;
-typedef boost::uint8_t uint8_t;
-#endif
+#include <cstdint>
#endif // _THRIFT_WINDOWS_CONFIG_H_
diff --git a/compiler/cpp/test/CMakeLists.txt b/compiler/cpp/test/CMakeLists.txt
index a09f23d..2bc7e9e 100644
--- a/compiler/cpp/test/CMakeLists.txt
+++ b/compiler/cpp/test/CMakeLists.txt
@@ -17,64 +17,11 @@
# under the License.
#
-
-if(${WITH_PLUGIN})
- include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
-
- # Make sure gen-cpp files can be included
- include_directories("${CMAKE_CURRENT_BINARY_DIR}")
-
- set(plugintest_SOURCES
- plugin/conversion_test.cc
- )
- add_executable(plugintest ${plugintest_SOURCES})
- if(WITH_SHARED_LIB AND NOT MSVC)
- target_link_libraries(plugintest
- thriftc
- ${Boost_LIBRARIES}
- )
- else()
- target_link_libraries(plugintest
- thriftc_static
- thrift_static
- ${Boost_LIBRARIES}
- )
- endif()
- add_test(NAME PluginUnitTest COMMAND plugintest)
-
- set(thrift-gen-mycpp_SOURCES
- ../src/thrift/generate/t_cpp_generator.cc
- plugin/cpp_plugin.cc
- )
- add_executable(thrift-gen-mycpp ${thrift-gen-mycpp_SOURCES})
- if(WITH_SHARED_LIB AND NOT MSVC)
- target_link_libraries(thrift-gen-mycpp thriftc)
- else()
- target_link_libraries(thrift-gen-mycpp thriftc_static thrift_static)
- endif()
-
- if(CMAKE_BUILD_TYPE STREQUAL "Debug")
- set(BUILDTYPE "Debug")
- else()
- # RelWithDebInfo generates binaries in "Release" directory too
- set(BUILDTYPE "Release")
- endif()
-
- set_directory_properties(PROPERTIES
- ADDITIONAL_MAKE_CLEAN_FILES gen-cpp
- ADDITIONAL_MAKE_CLEAN_FILES gen-mycpp)
-
- file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp)
- file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/gen-mycpp)
- add_test(NAME PluginIntegrationTest
- COMMAND ${CMAKE_COMMAND}
- -DTHRIFT_COMPILER=${THRIFT_COMPILER}
- -DBINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
- -DBUILDTYPE=${BUILDTYPE}
- -DCURDIR=${CMAKE_CURRENT_BINARY_DIR}
- -DSRCDIR=${CMAKE_CURRENT_SOURCE_DIR}
- -P ${CMAKE_CURRENT_SOURCE_DIR}/cpp_plugin_test.cmake)
-endif()
+# Unit tests for the compiler still require boost
+include(BoostMacros)
+REQUIRE_BOOST_HEADERS()
+set(BOOST_COMPONENTS unit_test_framework)
+REQUIRE_BOOST_LIBRARIES(BOOST_COMPONENTS)
file(GLOB KEYWORD_SAMPLES "${CMAKE_CURRENT_SOURCE_DIR}/keyword-samples/*.thrift")
foreach(LANG ${thrift_compiler_LANGS})
@@ -88,5 +35,9 @@
endforeach()
-find_package(PythonInterp REQUIRED)
-add_test(NAME StalenessCheckTest COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/compiler/staleness_check.py ${THRIFT_COMPILER})
+find_package(PythonInterp QUIET)
+if(PYTHONINTERP_FOUND)
+ add_test(NAME StalenessCheckTest COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/compiler/staleness_check.py ${THRIFT_COMPILER})
+else()
+ message(WARNING "Skipping StalenessCheckTest as there is no python interpreter available.")
+endif()
diff --git a/compiler/cpp/test/Makefile.am b/compiler/cpp/test/Makefile.am
index b7fc91d..9625834 100644
--- a/compiler/cpp/test/Makefile.am
+++ b/compiler/cpp/test/Makefile.am
@@ -26,35 +26,3 @@
AM_CPPFLAGS = $(BOOST_CPPFLAGS) -I$(top_srcdir)/compiler/cpp/src
AM_LDFLAGS = $(BOOST_LDFLAGS)
AM_CXXFLAGS = -Wall -Wextra -pedantic
-
-if WITH_PLUGIN
-check_PROGRAMS = plugintest
-
-noinst_PROGRAMS = thrift-gen-mycpp
-
-all-local: thrift-gen-bincat
-
-AM_CPPFLAGS += -I$(top_srcdir)/lib/cpp/src -I$(top_builddir)/lib/cpp/src
-
-plugintest_SOURCES = plugin/conversion_test.cc
-plugintest_LDADD = $(top_builddir)/compiler/cpp/libthriftc.la
-
-thrift_gen_mycpp_SOURCES = plugin/cpp_plugin.cc \
- plugin/t_cpp_generator.cc
-thrift_gen_mycpp_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/compiler/cpp -I$(top_srcdir)/compiler/cpp/src/generate
-thrift_gen_mycpp_LDADD = $(top_builddir)/compiler/cpp/libthriftc.la
-
-cpp_plugin_test.sh: thrift-gen-mycpp
-
-thrift-gen-bincat:
- cp bincat.sh $@
- chmod 755 $@
-
-plugin_stability_test.sh: thrift-gen-bincat
-
-TESTS = $(check_PROGRAMS) cpp_plugin_test.sh plugin_stability_test.sh
-
-clean-local:
- $(RM) -rf gen-cpp gen-mycpp gen-bincat thrift-gen-bincat
-
-endif
diff --git a/compiler/cpp/test/cpp_plugin_test.cmake b/compiler/cpp/test/cpp_plugin_test.cmake
deleted file mode 100644
index fd18281..0000000
--- a/compiler/cpp/test/cpp_plugin_test.cmake
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# 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.
-#
-
-file(MAKE_DIRECTORY ${CURDIR}/gen-cpp)
-execute_process(COMMAND ${THRIFT_COMPILER} -r -out ${CURDIR}/gen-cpp -gen cpp ${SRCDIR}/../../../test/Include.thrift)
-if(EXITCODE)
- message(FATAL_ERROR "FAILED: \"${ARGV}\": \"${EXITCODE}\"")
-endif()
-if(WIN32)
- set(ENV{PATH} "${BINDIR}/${BUILDTYPE};${BINDIR};$ENV{PATH}")
-else()
- set(ENV{PATH} "${BINDIR}:$ENV{PATH}")
-endif()
-
-file(MAKE_DIRECTORY ${CURDIR}/gen-mycpp)
-execute_process(COMMAND ${THRIFT_COMPILER} -r -out ${CURDIR}/gen-mycpp -gen mycpp ${SRCDIR}/../../../test/Include.thrift RESULT_VARIABLE EXITCODE)
-if(EXITCODE)
- message(FATAL_ERROR "FAILED: \"${EXITCODE}\"")
-endif()
-
-find_program(DIFF diff)
-if(DIFF)
- execute_process(COMMAND ${DIFF} -urN gen-cpp gen-mycpp RESULT_VARIABLE EXITCODE)
- if(EXITCODE)
- message(FATAL_ERROR "FAILED: \"${EXITCODE}\"")
- endif()
-else()
- message(WARNING "diff executable is not available. Not validating plugin-generated code.")
-endif()
diff --git a/compiler/cpp/test/plugin/conversion_test.cc b/compiler/cpp/test/plugin/conversion_test.cc
deleted file mode 100644
index 3c8d812..0000000
--- a/compiler/cpp/test/plugin/conversion_test.cc
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * 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.
- */
-
-#include "thrift/parse/t_program.h"
-#include "thrift/plugin/type_util.h"
-#include "thrift/plugin/plugin_types.h"
-
-#include <map>
-#include <vector>
-
-#include <boost/preprocessor.hpp>
-#include <boost/test/included/unit_test.hpp>
-#include <boost/test/parameterized_test.hpp>
-
-using namespace apache::thrift;
-using namespace boost::unit_test;
-
-namespace test_data {
-#define T_TEST_TYPES \
- BOOST_PP_TUPLE_TO_LIST(14, \
- (program, \
- base_type, \
- enum_value, \
- enum, \
- const_value, \
- const, \
- list, \
- set, \
- map, \
- field, \
- struct, \
- typedef, \
- function, \
- service))
-#define T_DELETE_TESTDATA(r, d, elem) \
- for (std::vector<t_##elem*>::reverse_iterator it = elem##s.rbegin(); it != elem##s.rend(); it++) \
- delete *it;
-#define T_DECL_TESTDATA(r, d, elem) static std::vector< ::t_##elem*> elem##s;
-BOOST_PP_LIST_FOR_EACH(T_DECL_TESTDATA, _, T_TEST_TYPES)
-#undef T_DECL_TESTDATA
-
-bool has_data = false;
-void cleanup() {
- if (has_data) {
- has_data = false;
- BOOST_PP_LIST_FOR_EACH(T_DELETE_TESTDATA, _, T_TEST_TYPES)
- }
-}
-
-void init_programs() {
- programs.push_back(new t_program("prog path", "prog_name"));
-}
-
-void init_base_types() {
- base_types.push_back(new ::t_base_type("name0", ::t_base_type::TYPE_VOID));
- base_types.push_back(new ::t_base_type("name1", ::t_base_type::TYPE_STRING));
- base_types.push_back(new ::t_base_type("name2", ::t_base_type::TYPE_BOOL));
- base_types.push_back(new ::t_base_type("name3", ::t_base_type::TYPE_I8));
- base_types.push_back(new ::t_base_type("name4", ::t_base_type::TYPE_I16));
- base_types.push_back(new ::t_base_type("name5", ::t_base_type::TYPE_I32));
- base_types.push_back(new ::t_base_type("name6", ::t_base_type::TYPE_I64));
- base_types.push_back(new ::t_base_type("name7", ::t_base_type::TYPE_DOUBLE));
-}
-
-void init_const_values() {
- const_values.push_back(new t_const_value(42));
- const_values.push_back(new t_const_value("foo"));
- {
- t_const_value* x = new t_const_value;
- x->set_double(3.1415);
- const_values.push_back(x);
- }
- {
- t_const_value* x = new t_const_value;
- x->set_identifier("bar");
- x->set_enum(enums[0]);
- const_values.push_back(x);
- }
- {
- t_const_value* x = new t_const_value;
- x->set_map();
- x->add_map(const_values[0], const_values[1]);
- x->add_map(const_values[1], const_values[0]);
- const_values.push_back(x);
- }
- {
- t_const_value* x = new t_const_value;
- x->set_list();
- x->add_list(const_values[0]);
- x->add_list(const_values[1]);
- const_values.push_back(x);
- }
-}
-
-void init_consts() {
- // base_type/enum indexes for this and other tests are arbitrary
- consts.push_back(new t_const(base_types[2], "aaa", const_values[0]));
- consts.back()->set_doc("soem doc");
- consts.push_back(new t_const(base_types[3], "bbb", const_values[1]));
-}
-
-void init_enum_values() {
- enum_values.push_back(new t_enum_value("VAL1", 11));
- enum_values.back()->set_doc("enum doc 1");
- enum_values.back()->annotations_.insert(std::make_pair("anno1", "val1"));
-
- enum_values.push_back(new t_enum_value("VAL2", 22));
-}
-
-void init_enums() {
- enums.push_back(new t_enum(programs[0]));
- enums.back()->set_doc("enum doc 1");
- enums.back()->annotations_.insert(std::make_pair("anno1", "val1"));
- enums.back()->set_name("fooo");
- enums.back()->append(enum_values[0]);
- enums.back()->append(enum_values[1]);
-}
-
-void init_lists() {
- lists.push_back(new t_list(enums[0]));
- lists.push_back(new t_list(base_types[5]));
- lists.back()->set_cpp_name("list_cpp_name_1");
-}
-void init_sets() {
- sets.push_back(new t_set(base_types[4]));
- sets.push_back(new t_set(enums[0]));
- sets.back()->set_cpp_name("set_cpp_name_1");
-}
-void init_maps() {
- maps.push_back(new t_map(base_types[4], base_types[1]));
- maps.push_back(new t_map(base_types[5], enums[0]));
- maps.back()->set_cpp_name("map_cpp_name_1");
-}
-
-void init_typedefs() {
- typedefs.push_back(new t_typedef(programs[0], base_types[3], "VAL1"));
-}
-void init_fields() {
- fields.push_back(new t_field(base_types[1], "f1"));
- fields.back()->set_reference(false);
- fields.back()->set_req(t_field::T_OPTIONAL);
- fields.push_back(new t_field(base_types[2], "f2", 9));
- fields.back()->set_reference(true);
- fields.push_back(new t_field(base_types[3], "f3", 11));
- fields.back()->set_req(t_field::T_REQUIRED);
- fields.back()->set_value(const_values[0]);
-}
-void init_structs() {
- structs.push_back(new t_struct(programs[0], "struct1"));
- structs.back()->append(fields[0]);
- structs.back()->append(fields[1]);
- structs.push_back(new t_struct(programs[0], "union1"));
- structs.back()->append(fields[0]);
- structs.back()->append(fields[1]);
- structs.back()->set_union(true);
- structs.push_back(new t_struct(programs[0], "xcept1"));
- structs.back()->set_xception(true);
-}
-void init_functions() {
- structs.push_back(new t_struct(programs[0], "errs1"));
- t_struct* errors = structs.back();
- structs.push_back(new t_struct(programs[0], "args1"));
- t_struct* arglist = structs.back();
- functions.push_back(new t_function(base_types[0], "func1", errors, arglist, false));
- functions.push_back(new t_function(base_types[0], "func2", errors, arglist, true));
-}
-void init_services() {
- services.push_back(new t_service(programs[0]));
- services.back()->set_doc("srv1 doc");
- services.back()->set_name("srv1");
- services.back()->add_function(functions[0]);
- services.back()->add_function(functions[1]);
-
- services.push_back(new t_service(programs[0]));
- services.back()->set_name("srv2");
- services.back()->set_extends(services[0]);
-}
-
-std::vector<t_type*> types;
-void init_types() {
-#define T_COPY_TYPES(type) std::copy(type##s.begin(), type##s.end(), std::back_inserter(types))
- T_COPY_TYPES(base_type);
- T_COPY_TYPES(enum);
- T_COPY_TYPES(typedef);
- T_COPY_TYPES(struct);
- T_COPY_TYPES(list);
- T_COPY_TYPES(set);
- T_COPY_TYPES(map);
-// T_COPY_TYPES(service);
-#undef T_COPY_TYPES
-}
-
-void init() {
- if (!has_data) {
- has_data = true;
-#define T_INIT_TESTDATA(r, d, elem) init_##elem##s();
- BOOST_PP_LIST_FOR_EACH(T_INIT_TESTDATA, _, T_TEST_TYPES)
- init_types();
-#undef T_INIT_TESTDATA
- }
-}
-}
-struct GlobalFixture {
- ~GlobalFixture() { test_data::cleanup(); }
-};
-#if (BOOST_VERSION >= 105900)
-BOOST_GLOBAL_FIXTURE(GlobalFixture);
-#else
-BOOST_GLOBAL_FIXTURE(GlobalFixture)
-#endif
-
-void migrate_global_cache() {
- plugin::TypeRegistry reg;
- plugin_output::get_global_cache(reg);
- plugin::set_global_cache(reg);
- plugin_output::clear_global_cache();
-}
-template <typename T>
-T* round_trip(T* t) {
- typename plugin::ToType<T>::type p;
- plugin::clear_global_cache();
- plugin_output::clear_global_cache();
- plugin_output::convert(t, p);
- migrate_global_cache();
- return plugin::convert(p);
-}
-
-void test_base_type(::t_base_type* sut) {
- plugin::t_base_type p;
- plugin_output::convert(sut, p);
- boost::scoped_ptr< ::t_base_type> sut2(plugin::convert(p));
-
-#define THRIFT_CHECK(r, data, elem) BOOST_PP_EXPAND(BOOST_CHECK_EQUAL(data elem, sut2->elem));
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(7,
- (is_void(),
- is_string(),
- is_bool(),
- is_string_list(),
- is_binary(),
- is_string_enum(),
- is_base_type())))
-}
-
-void test_const_value(t_const_value* sut) {
- boost::scoped_ptr<t_const_value> sut2(round_trip(sut));
-
- BOOST_CHECK_EQUAL(sut->get_type(), sut2->get_type());
- switch (sut->get_type()) {
-#define T_CONST_VALUE_CASE(type, name) \
- case t_const_value::type: \
- BOOST_CHECK_EQUAL(sut->get_##name(), sut2->get_##name()); \
- break
- T_CONST_VALUE_CASE(CV_INTEGER, integer);
- T_CONST_VALUE_CASE(CV_DOUBLE, double);
- T_CONST_VALUE_CASE(CV_STRING, string);
- T_CONST_VALUE_CASE(CV_IDENTIFIER, identifier);
-#undef T_CONST_VALUE_CASE
- case t_const_value::CV_MAP:
- BOOST_CHECK_EQUAL(sut->get_map().size(), sut2->get_map().size());
- {
- std::map<t_const_value::t_const_value_type, t_const_value::t_const_value_type> sut_values;
- for (std::map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator it = sut->get_map().begin();
- it != sut->get_map().end(); it++) {
- sut_values[it->first->get_type()] = it->second->get_type();
- }
- std::map<t_const_value::t_const_value_type, t_const_value::t_const_value_type> sut2_values;
- for (std::map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator it = sut2->get_map().begin();
- it != sut2->get_map().end(); it++) {
- sut2_values[it->first->get_type()] = it->second->get_type();
- }
- BOOST_CHECK_EQUAL(sut_values.begin()->first, sut2_values.begin()->first);
- BOOST_CHECK_EQUAL(sut_values.begin()->second, sut2_values.begin()->second);
- }
- break;
- case t_const_value::CV_LIST:
- BOOST_CHECK_EQUAL(sut->get_list().size(), sut2->get_list().size());
- BOOST_CHECK_EQUAL(sut->get_list().front()->get_type(), sut2->get_list().front()->get_type());
- break;
- default:
- BOOST_ASSERT(false);
- break;
- }
-}
-
-void test_const(t_const* sut) {
- boost::scoped_ptr< ::t_const> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(4,
- (get_type()->get_name(),
- get_name(),
- get_value()->get_type(),
- get_doc())))
-}
-
-void test_enum_value(t_enum_value* sut) {
- boost::scoped_ptr<t_enum_value> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(3, (get_name(), get_value(), get_doc())))
-}
-
-void test_enum(t_enum* sut) {
- boost::scoped_ptr< ::t_enum> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(6,
- (get_name(),
- get_min_value()->get_value(),
- get_max_value()->get_value(),
- get_constant_by_value(11)->get_value(),
- get_constant_by_name("VAL1")->get_value(),
- get_doc())))
-}
-
-void test_list(t_list* sut) {
- boost::scoped_ptr<t_list> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(4,
- (get_elem_type()->get_name(),
- has_cpp_name(),
- get_doc(),
- get_name())))
- if (sut->has_cpp_name())
- BOOST_CHECK_EQUAL(sut->get_cpp_name(), sut2->get_cpp_name());
-}
-void test_set(t_set* sut) {
- boost::scoped_ptr<t_set> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(4,
- (get_elem_type()->get_name(),
- has_cpp_name(),
- get_doc(),
- get_name())))
- if (sut->has_cpp_name())
- BOOST_CHECK_EQUAL(sut->get_cpp_name(), sut2->get_cpp_name());
-}
-void test_map(t_map* sut) {
- boost::scoped_ptr<t_map> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(5,
- (get_key_type()->get_name(),
- get_val_type()->get_name(),
- has_cpp_name(),
- get_doc(),
- get_name())))
- if (sut->has_cpp_name())
- BOOST_CHECK_EQUAL(sut->get_cpp_name(), sut2->get_cpp_name());
-}
-
-void test_typedef(t_typedef* sut) {
- boost::scoped_ptr<t_typedef> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(4,
- (get_doc(),
- get_name(),
- get_symbolic(),
- is_forward_typedef())))
-}
-
-void test_type(t_type* sut) {
- boost::scoped_ptr<t_type> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(15,
- (is_void(),
- is_base_type(),
- is_string(),
- is_bool(),
- is_typedef(),
- is_enum(),
- is_struct(),
- is_xception(),
- is_container(),
- is_list(),
- is_set(),
- is_map(),
- is_service(),
- get_doc(),
- get_name())))
-}
-
-void test_field(t_field* sut) {
- boost::scoped_ptr<t_field> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(5,
- (get_req(),
- get_reference(),
- get_key(),
- get_doc(),
- get_name())))
- if (sut->get_value()) {
- THRIFT_CHECK(, sut->, get_value()->get_type());
- } else {
- BOOST_CHECK(!sut2->get_value());
- }
- if (sut->get_type()) {
- THRIFT_CHECK(, sut->, get_type()->get_name());
- } else {
- BOOST_CHECK(!sut2->get_type());
- }
-}
-void test_struct(t_struct* sut) {
- boost::scoped_ptr<t_struct> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(5,
- (is_union(),
- is_xception(),
- is_struct(),
- get_doc(),
- get_name())))
-}
-
-void test_function(t_function* sut) {
- boost::scoped_ptr<t_function> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(
- THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(4, (get_doc(), get_name(), get_returntype()->get_name(), is_oneway())))
-}
-void test_service(t_service* sut) {
- boost::scoped_ptr<t_service> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK,
- sut->,
- BOOST_PP_TUPLE_TO_LIST(3, (get_doc(), get_name(), get_functions().size())))
- if (sut->get_extends()) {
- THRIFT_CHECK(, sut->, get_extends()->get_name());
- } else {
- BOOST_CHECK(!sut2->get_extends());
- }
-}
-
-void test_program(t_program* sut) {
- boost::scoped_ptr<t_program> sut2(round_trip(sut));
-
- BOOST_PP_LIST_FOR_EACH(THRIFT_CHECK, sut->, BOOST_PP_TUPLE_TO_LIST(2, (get_doc(), get_name())))
-}
-boost::unit_test::test_suite* do_init_unit_test_suite() {
- test_data::init();
- test_suite* ts = BOOST_TEST_SUITE("PluginConversionTest");
-
-#define T_TEST_CASE(r, d, type) \
- ts->add(BOOST_PARAM_TEST_CASE(test_##type, test_data::type##s.begin(), test_data::type##s.end()));
- BOOST_PP_LIST_FOR_EACH(T_TEST_CASE, _, T_TEST_TYPES)
- T_TEST_CASE(_, _, type)
-#undef T_TEST_CASE
- return ts;
-}
-
-#ifdef BOOST_TEST_DYN_LINK
-bool init_unit_test_suite() {
- framework::master_test_suite().add(do_init_unit_test_suite());
- return true;
-}
-int main(int argc, char* argv[]) {
- return ::boost::unit_test::unit_test_main(&init_unit_test_suite, argc, argv);
-}
-#else
-boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) {
- return do_init_unit_test_suite();
-}
-#endif
diff --git a/compiler/cpp/test/plugin/cpp_plugin.cc b/compiler/cpp/test/plugin/cpp_plugin.cc
deleted file mode 100644
index 6cc19f2..0000000
--- a/compiler/cpp/test/plugin/cpp_plugin.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-
-#include "thrift/plugin/plugin.h"
-#include "thrift/generate/t_generator.h"
-
-namespace apache {
-namespace thrift {
-namespace plugin {
-
-class MyCppGenerator : public GeneratorPlugin {
- virtual int generate(::t_program* program,
- const std::map<std::string, std::string>& parsed_options) {
- t_generator* gen = t_generator_registry::get_generator(program, "cpp", parsed_options, "");
- gen->generate_program();
- delete gen;
- return 0;
- }
-};
-}
-}
-}
-
-int main(int argc, char* argv[]) {
- apache::thrift::plugin::MyCppGenerator p;
- return p.exec(argc, argv);
-}
diff --git a/compiler/cpp/test/plugin_stability_test.sh b/compiler/cpp/test/plugin_stability_test.sh
deleted file mode 100755
index eb7c93d..0000000
--- a/compiler/cpp/test/plugin_stability_test.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-
-#
-# 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.
-#
-
-# this file is intended to be invoked by make.
-#
-# This file runs the compiler twice, using a plugin that just invokes
-# /bin/cat, and compares the output. If GeneratorInput is
-# nondeterminsitic, you'd expect the output to differ from run-to-run.
-# So this tests that in fact, the output is stable from run-to-run.
-set -e
-mkdir -p gen-bincat
-PATH=.:"$PATH" ../thrift -r -gen bincat ../../../test/Include.thrift > gen-bincat/1.ser
-PATH=.:"$PATH" ../thrift -r -gen bincat ../../../test/Include.thrift > gen-bincat/2.ser
-diff --binary gen-bincat/1.ser gen-bincat/2.ser
diff --git a/compiler/cpp/tests/CMakeLists.txt b/compiler/cpp/tests/CMakeLists.txt
index e2b100c..fde9073 100644
--- a/compiler/cpp/tests/CMakeLists.txt
+++ b/compiler/cpp/tests/CMakeLists.txt
@@ -96,36 +96,36 @@
endmacro()
# The following compiler with unit tests can be enabled or disabled
-THRIFT_ADD_COMPILER(c_glib "Enable compiler for C with Glib" OFF)
-THRIFT_ADD_COMPILER(cpp "Enable compiler for C++" OFF)
-THRIFT_ADD_COMPILER(java "Enable compiler for Java" OFF)
THRIFT_ADD_COMPILER(as3 "Enable compiler for ActionScript 3" OFF)
-THRIFT_ADD_COMPILER(dart "Enable compiler for Dart" OFF)
-THRIFT_ADD_COMPILER(haxe "Enable compiler for Haxe" OFF)
+THRIFT_ADD_COMPILER(c_glib "Enable compiler for C with Glib" OFF)
+THRIFT_ADD_COMPILER(cl "Enable compiler for Common LISP" OFF)
+THRIFT_ADD_COMPILER(cpp "Enable compiler for C++" OFF)
THRIFT_ADD_COMPILER(csharp "Enable compiler for C#" OFF)
-THRIFT_ADD_COMPILER(netcore "Enable compiler for .NET Core" ON)
-THRIFT_ADD_COMPILER(py "Enable compiler for Python 2.0" OFF)
-THRIFT_ADD_COMPILER(rb "Enable compiler for Ruby" OFF)
-THRIFT_ADD_COMPILER(perl "Enable compiler for Perl" OFF)
-THRIFT_ADD_COMPILER(php "Enable compiler for PHP" OFF)
+THRIFT_ADD_COMPILER(d "Enable compiler for D" OFF)
+THRIFT_ADD_COMPILER(dart "Enable compiler for Dart" OFF)
+THRIFT_ADD_COMPILER(delphi "Enable compiler for Delphi" OFF)
THRIFT_ADD_COMPILER(erl "Enable compiler for Erlang" OFF)
-THRIFT_ADD_COMPILER(cocoa "Enable compiler for Cocoa Objective-C" OFF)
-THRIFT_ADD_COMPILER(swift "Enable compiler for Cocoa Swift" OFF)
-THRIFT_ADD_COMPILER(st "Enable compiler for Smalltalk" OFF)
-THRIFT_ADD_COMPILER(ocaml "Enable compiler for OCaml" OFF)
+THRIFT_ADD_COMPILER(go "Enable compiler for Go" OFF)
+THRIFT_ADD_COMPILER(gv "Enable compiler for GraphViz" OFF)
+THRIFT_ADD_COMPILER(haxe "Enable compiler for Haxe" OFF)
THRIFT_ADD_COMPILER(hs "Enable compiler for Haskell" OFF)
-THRIFT_ADD_COMPILER(xsd "Enable compiler for XSD" OFF)
THRIFT_ADD_COMPILER(html "Enable compiler for HTML Documentation" OFF)
+THRIFT_ADD_COMPILER(java "Enable compiler for Java" OFF)
+THRIFT_ADD_COMPILER(javame "Enable compiler for Java ME" OFF)
THRIFT_ADD_COMPILER(js "Enable compiler for JavaScript" OFF)
THRIFT_ADD_COMPILER(json "Enable compiler for JSON" OFF)
-THRIFT_ADD_COMPILER(javame "Enable compiler for Java ME" OFF)
-THRIFT_ADD_COMPILER(delphi "Enable compiler for Delphi" OFF)
-THRIFT_ADD_COMPILER(go "Enable compiler for Go" OFF)
-THRIFT_ADD_COMPILER(d "Enable compiler for D" OFF)
THRIFT_ADD_COMPILER(lua "Enable compiler for Lua" OFF)
-THRIFT_ADD_COMPILER(gv "Enable compiler for GraphViz" OFF)
+THRIFT_ADD_COMPILER(netcore "Enable compiler for .NET Core" ON)
+THRIFT_ADD_COMPILER(ocaml "Enable compiler for OCaml" OFF)
+THRIFT_ADD_COMPILER(perl "Enable compiler for Perl" OFF)
+THRIFT_ADD_COMPILER(php "Enable compiler for PHP" OFF)
+THRIFT_ADD_COMPILER(py "Enable compiler for Python 2.0" OFF)
+THRIFT_ADD_COMPILER(rb "Enable compiler for Ruby" OFF)
THRIFT_ADD_COMPILER(rs "Enable compiler for Rust" OFF)
+THRIFT_ADD_COMPILER(st "Enable compiler for Smalltalk" OFF)
+THRIFT_ADD_COMPILER(swift "Enable compiler for Swift" OFF)
THRIFT_ADD_COMPILER(xml "Enable compiler for XML" OFF)
+THRIFT_ADD_COMPILER(xsd "Enable compiler for XSD" OFF)
# Thrift is looking for include files in the src directory
# we also add the current binary directory for generated files
@@ -150,4 +150,4 @@
target_link_libraries(thrift_compiler_tests thrift_compiler)
enable_testing()
-add_test(NAME ThriftTests COMMAND thrift_compiler_tests)
\ No newline at end of file
+add_test(NAME ThriftTests COMMAND thrift_compiler_tests)
diff --git a/composer.json b/composer.json
index 3695b8c..1d3a6c0 100644
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,7 @@
{
"name": "apache/thrift",
"description": "Apache Thrift RPC system",
- "homepage": "https://thrift.apache.org/",
+ "homepage": "http://thrift.apache.org",
"type": "library",
"keywords": ["RPC"],
"license": "Apache-2.0",
diff --git a/configure.ac b/configure.ac
index 835ba78..391cdb3 100755
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
AC_PREREQ(2.65)
AC_CONFIG_MACRO_DIR([./aclocal])
-AC_INIT([thrift], [0.12.1])
+AC_INIT([thrift], [0.13.0])
AC_CONFIG_AUX_DIR([.])
@@ -102,10 +102,7 @@
AC_PROG_RANLIB
AC_LANG([C++])
-AX_CXX_COMPILE_STDCXX_11([noext], [optional])
-if test "$ac_success" = "no"; then
- CXXFLAGS="$CXXFLAGS -Wno-variadic-macros -Wno-long-long -Wno-c++11-long-long"
-fi
+AX_CXX_COMPILE_STDCXX_11([noext], [mandatory])
AM_EXTRA_RECURSIVE_TARGETS([style])
AC_SUBST(CPPSTYLE_CMD, 'find . -type f \( -iname "*.h" -or -iname "*.cpp" -or -iname "*.cc" -or -iname "*.tcc" \) -printf "Reformatting: %h/%f\n" -exec clang-format -i {} \;')
@@ -131,6 +128,7 @@
with_haskell="no"
with_haxe="no"
with_dotnetcore="no"
+ with_netstd="no"
with_perl="no"
with_php="no"
with_php_extension="no"
@@ -142,6 +140,7 @@
with_nodets="no"
with_lua="no"
with_rs="no"
+ with_swift="no"
fi
AX_THRIFT_LIB(as3, [as3], yes)
@@ -159,7 +158,7 @@
AX_THRIFT_LIB(cpp, [C++], yes)
have_cpp=no
if test "$with_cpp" = "yes"; then
- AX_BOOST_BASE([1.53.0])
+ AX_BOOST_BASE([1.56.0])
if test "x$succeeded" = "xyes" ; then
AC_SUBST([BOOST_LIB_DIR], [$(echo "$BOOST_LDFLAGS" | sed -e 's/^\-L//')])
AC_SUBST([BOOST_CHRONO_LDADD], [$(echo "$BOOST_LIB_DIR/libboost_chrono.a")])
@@ -170,24 +169,12 @@
have_cpp="yes"
fi
- AX_LIB_EVENT([1.0])
+ AX_LIB_EVENT([2.0])
have_libevent=$success
AX_LIB_ZLIB([1.2.3])
have_zlib=$success
- AX_THRIFT_LIB(qt4, [Qt], yes)
- have_qt=no
- if test "$with_qt4" = "yes"; then
- PKG_CHECK_MODULES([QT], [QtCore >= 4.3, QtNetwork >= 4.3], have_qt=yes, have_qt=no)
- fi
- if test "$have_qt" = "yes"; then
- AC_PATH_PROGS([QT_MOC], [moc-qt4 moc], "fail")
- if test "$QT_MOC" = "fail"; then
- have_qt=no
- fi
- fi
-
AX_THRIFT_LIB(qt5, [Qt5], yes)
have_qt5=no
qt_reduce_reloc=""
@@ -206,7 +193,6 @@
AM_CONDITIONAL([WITH_CPP], [test "$have_cpp" = "yes"])
AM_CONDITIONAL([AMX_HAVE_LIBEVENT], [test "$have_libevent" = "yes"])
AM_CONDITIONAL([AMX_HAVE_ZLIB], [test "$have_zlib" = "yes"])
-AM_CONDITIONAL([AMX_HAVE_QT], [test "$have_qt" = "yes"])
AM_CONDITIONAL([AMX_HAVE_QT5], [test "$have_qt5" = "yes"])
AM_CONDITIONAL([QT5_REDUCE_RELOCATIONS], [test "x$qt_reduce_reloc" != "x"])
@@ -221,9 +207,9 @@
fi
AM_CONDITIONAL(WITH_C_GLIB, [test "$have_glib2" = "yes" -a "$have_gobject2" = "yes"])
-echo "OpenSSL check"
+# echo "OpenSSL check"
if test "$have_cpp" = "yes" -o "$have_c_glib" = "yes"; then
- echo "Have cpp or c so we check for OpenSSL"
+ # echo "Have cpp or c so we check for OpenSSL"
AX_CHECK_OPENSSL()
fi
@@ -264,7 +250,7 @@
if test "$with_erlang" = "yes"; then
AC_ERLANG_PATH_ERL
AC_ERLANG_PATH_ERLC
- AC_PATH_PROG([REBAR], [rebar])
+ AC_PATH_PROG([REBAR], [rebar3])
if test -n "$ERLC" ; then
AC_ERLANG_SUBST_LIB_DIR
# Install into the detected Erlang directory instead of $libdir/erlang/lib
@@ -338,10 +324,13 @@
# It's distro specific and far from ideal but needed to cross test py2-3 at once.
# TODO: find "python2" if it's 3.x
have_py3="no"
-if python --version 2>&1 | grep -q "Python 2"; then
- AC_PATH_PROGS([PYTHON3], [python3 python3.5 python35 python3.4 python34])
- if test -n "$PYTHON3"; then
- have_py3="yes"
+AX_THRIFT_LIB(py3, [Py3], yes)
+if test "$with_py3" = "yes"; then
+ if $PYTHON --version 2>&1 | grep -q "Python 2"; then
+ AC_PATH_PROGS([PYTHON3], [python3 python3.7 python37 python3.6 python36 python3.5 python35 python3.4 python34])
+ if test -n "$PYTHON3"; then
+ have_py3="yes"
+ fi
fi
fi
AM_CONDITIONAL(WITH_PY3, [test "$have_py3" = "yes"])
@@ -459,6 +448,16 @@
AM_CONDITIONAL(WITH_GO, [test "$have_go" = "yes"])
AM_CONDITIONAL([GOVERSION_LT_17], [test "$go_version_lt_17" = "yes"])
+AX_THRIFT_LIB(swift, [Swift], yes)
+have_swift="no"
+if test "$with_swift" = "yes"; then
+ AC_PATH_PROG([SWIFT], [swift])
+ if test "x$SWIFT" != "x" -a "x$SWIFT" != "x"; then
+ have_swift="yes"
+ fi
+fi
+AM_CONDITIONAL([WITH_SWIFT], [test "$have_swift" = "yes"])
+
AX_THRIFT_LIB(rs, [Rust], yes)
have_rs="no"
if test "$with_rs" = "yes"; then
@@ -510,7 +509,7 @@
AX_PROG_DOTNETCORE_VERSION( [2.0.0], have_dotnetcore="yes", have_dotnetcore="no")
fi
fi
-AM_CONDITIONAL(WITH_DOTNETCORE, [test "$have_dotnetcore" = "yes"])
+AM_CONDITIONAL(WITH_DOTNET, [test "$have_dotnetcore" = "yes"])
AX_THRIFT_LIB(d, [D], yes)
@@ -609,20 +608,6 @@
fi
AM_CONDITIONAL(WITH_TESTS, [test "$have_tests" = "yes"])
-AC_ARG_ENABLE([plugin],
- AS_HELP_STRING([--enable-plugin], [build compiler plugin support [default=no]]),
- [], enable_plugin=no
-)
-have_plugin=yes
-if test "$have_cpp" = "no" ; then
- have_plugin="no"
-fi
-if test "$enable_plugin" = "no"; then
- have_plugin="no"
-fi
-AC_CONFIG_LINKS([compiler/cpp/test/plugin/t_cpp_generator.cc:compiler/cpp/src/thrift/generate/t_cpp_generator.cc])
-AM_CONDITIONAL(WITH_PLUGIN, [test "$have_plugin" = "yes"])
-
AC_ARG_ENABLE([tutorial],
AS_HELP_STRING([--enable-tutorial], [build tutorial [default=yes]]),
[], enable_tutorial=yes
@@ -788,24 +773,6 @@
AC_SUBST(GCOV_CXXFLAGS)
AC_SUBST(GCOV_LDFLAGS)
-AC_ARG_ENABLE(boostthreads,
- [ --enable-boostthreads use boost threads, instead of POSIX pthread (experimental) ],
- [case "${enableval}" in
- yes) ENABLE_BOOSTTHREADS=1 ;;
- no) ENABLE_BOOSTTHREADS=0 ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-cov) ;;
- esac],
- [ENABLE_BOOSTTHREADS=2])
-
-
-if test "x[$]ENABLE_BOOSTTHREADS" = "x1"; then
- AC_MSG_WARN(enable boostthreads)
- AC_DEFINE([USE_BOOST_THREAD], [1], [experimental --enable-boostthreads that replaces POSIX pthread by boost::thread])
- LIBS="-lboost_thread $LIBS"
-fi
-
-AM_CONDITIONAL([WITH_BOOSTTHREADS], [test "x[$]ENABLE_BOOSTTHREADS" = "x1"])
-
AC_CONFIG_HEADERS(config.h:config.hin)
AC_CONFIG_HEADERS(lib/cpp/src/thrift/config.h:config.hin)
AC_CONFIG_HEADERS(lib/c_glib/src/thrift/config.h:config.hin)
@@ -823,7 +790,6 @@
Makefile
compiler/cpp/Makefile
compiler/cpp/src/Makefile
- compiler/cpp/src/thrift/plugin/Makefile
compiler/cpp/test/Makefile
compiler/cpp/src/thrift/version.h
lib/Makefile
@@ -833,7 +799,6 @@
lib/cpp/test/Makefile
lib/cpp/thrift-nb.pc
lib/cpp/thrift-z.pc
- lib/cpp/thrift-qt.pc
lib/cpp/thrift-qt5.pc
lib/cpp/thrift.pc
lib/c_glib/Makefile
@@ -854,6 +819,7 @@
lib/json/Makefile
lib/json/test/Makefile
lib/netcore/Makefile
+ lib/netstd/Makefile
lib/nodejs/Makefile
lib/nodets/Makefile
lib/perl/Makefile
@@ -866,6 +832,8 @@
lib/rs/Makefile
lib/rs/test/Makefile
lib/lua/Makefile
+ lib/swift/Makefile
+ lib/ts/Makefile
lib/xml/Makefile
lib/xml/test/Makefile
test/Makefile
@@ -880,6 +848,7 @@
test/hs/Makefile
test/lua/Makefile
test/netcore/Makefile
+ test/netstd/Makefile
test/php/Makefile
test/dart/Makefile
test/perl/Makefile
@@ -899,6 +868,7 @@
tutorial/java/Makefile
tutorial/js/Makefile
tutorial/netcore/Makefile
+ tutorial/netstd/Makefile
tutorial/nodejs/Makefile
tutorial/dart/Makefile
tutorial/py/Makefile
@@ -946,6 +916,8 @@
AC_SUBST([MAYBE_LUA])
if test "$have_rs" = "yes" ; then MAYBE_RS="rs" ; else MAYBE_RS="" ; fi
AC_SUBST([MAYBE_RS])
+if test "$have_swift" = "yes" ; then MAYBE_SWIFT="swift" ; else MAYBE_SWIFT="" ; fi
+AC_SUBST([MAYBE_SWIFT])
if test "$have_dotnetcore" = "yes" ; then MAYBE_DOTNETCORE="netcore" ; else MAYBE_DOTNETCORE="" ; fi
AC_SUBST([MAYBE_DOTNETCORE])
if test "$have_cl" = "yes" ; then MAYBE_CL="cl" ; else MAYBE_CL="" ; fi
@@ -965,6 +937,7 @@
echo "Building D Library ........... : $have_d"
echo "Building Dart Library ........ : $have_dart"
echo "Building dotnetcore Library .. : $have_dotnetcore"
+echo "Building .NET Standard Library : $have_dotnetcore"
echo "Building Erlang Library ...... : $have_erlang"
echo "Building Go Library .......... : $have_go"
echo "Building Haskell Library ..... : $have_haskell"
@@ -974,11 +947,11 @@
echo "Building NodeJS Library ...... : $have_nodejs"
echo "Building Perl Library ........ : $have_perl"
echo "Building PHP Library ......... : $have_php"
-echo "Building Plugin Support ...... : $have_plugin"
echo "Building Python Library ...... : $have_python"
echo "Building Py3 Library ......... : $have_py3"
echo "Building Ruby Library ........ : $have_ruby"
echo "Building Rust Library ........ : $have_rs"
+echo "Building Swift Library ....... : $have_swift"
if test "$have_as3" = "yes" ; then
echo
@@ -1003,7 +976,6 @@
echo " C++ compiler .............. : $CXX"
echo " Build TZlibTransport ...... : $have_zlib"
echo " Build TNonblockingServer .. : $have_libevent"
- echo " Build TQTcpServer (Qt4) ... : $have_qt"
echo " Build TQTcpServer (Qt5) ... : $have_qt5"
echo " C++ compiler version ...... : $($CXX --version | head -1)"
fi
@@ -1034,6 +1006,12 @@
echo " Using .NET Core ........... : $DOTNETCORE"
echo " Using .NET Core version ... : $DOTNETCORE_VERSION"
fi
+if test "$have_dotnetcore" = "yes" ; then
+ echo
+ echo ".NET Standard Library:"
+ echo " Using dotnet .............. : $DOTNETCORE"
+ echo " Using dotnet version ...... : $DOTNETCORE_VERSION"
+fi
if test "$have_erlang" = "yes" ; then
echo
echo "Erlang Library:"
@@ -1119,6 +1097,12 @@
echo " Using rustc................ : $RUSTC"
echo " Using Rust version......... : $($RUSTC --version)"
fi
+if test "$have_swift" = "yes" ; then
+ echo
+ echo "Swift Library:"
+ echo " Using Swift ............... : $SWIFT"
+ echo " Using Swift version ....... : $($SWIFT --version | head -1)"
+fi
echo
echo "If something is missing that you think should be present,"
echo "please skim the output of configure to find the missing"
diff --git a/contrib/Rebus/Properties/AssemblyInfo.cs b/contrib/Rebus/Properties/AssemblyInfo.cs
index 4f26553..e476eab 100644
--- a/contrib/Rebus/Properties/AssemblyInfo.cs
+++ b/contrib/Rebus/Properties/AssemblyInfo.cs
@@ -34,5 +34,5 @@
[assembly: Guid("0af10984-40d3-453d-b1e5-421529e8c7e2")]
-[assembly: AssemblyVersion("0.12.1.0")]
-[assembly: AssemblyFileVersion("0.12.1.0")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/contrib/Vagrantfile b/contrib/Vagrantfile
index 3bcc46a..b340563 100644
--- a/contrib/Vagrantfile
+++ b/contrib/Vagrantfile
@@ -37,13 +37,13 @@
# Install Dependencies
# ---
# General dependencies
-sudo apt-get install -qq automake libtool flex bison pkg-config g++ libssl-dev make libqt4-dev git debhelper
+sudo apt-get install -qq automake libtool flex bison pkg-config g++ libssl-dev make git debhelper
# C++ dependencies
sudo apt-get install -qq libboost-dev libboost-test-dev libboost-program-options-dev libboost-filesystem-dev libboost-system-dev libevent-dev
# Java dependencies
-sudo apt-get install -qq ant openjdk-7-jdk maven
+sudo apt-get install -qq ant openjdk-8-jdk maven
# Python dependencies
sudo apt-get install -qq python-all python-all-dev python-all-dbg python-setuptools python-support python-six python3-six
@@ -89,8 +89,8 @@
# Customize the system
# ---
-# Default java to latest 1.7 version
-update-java-alternatives -s java-1.7.0-openjdk-amd64
+# Default java to latest 1.8 version
+update-java-alternatives -s java-1.8.0-openjdk-amd64
# PHPUnit package broken in ubuntu. see https://bugs.launchpad.net/ubuntu/+source/phpunit/+bug/701544
sudo apt-get upgrade pear
diff --git a/contrib/fb303/java/build.xml b/contrib/fb303/java/build.xml
index 591a4cb..7a1b8f1 100755
--- a/contrib/fb303/java/build.xml
+++ b/contrib/fb303/java/build.xml
@@ -136,9 +136,9 @@
<remoteRepository refid="central"/>
<remoteRepository refid="apache"/>
<license name="The Apache Software License, Version 2.0" url="${license}"/>
- <scm connection="scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git"
- developerConnection="scm:git:https://git-wip-us.apache.org/repos/asf/thrift.git"
- url="https://git-wip-us.apache.org/repos/asf?p=thrift.git"
+ <scm connection="scm:git:https://github.com/apache/thrift.git"
+ developerConnection="scm:git:https://github.com/apache/thrift.git"
+ url="https://github.com/apache/thrift"
/>
<!-- Thrift Developers -->
<developer id="mcslee" name="Mark Slee"/>
diff --git a/contrib/fb303/py/setup.py b/contrib/fb303/py/setup.py
index 8ad066c..d27c296 100644
--- a/contrib/fb303/py/setup.py
+++ b/contrib/fb303/py/setup.py
@@ -26,9 +26,9 @@
from distutils.core import setup, Extension, Command
setup(name='thrift_fb303',
- version='0.12.1',
+ version='1.0.0',
description='Python bindings for the Apache Thrift FB303',
- author=['Thrift Developers'],
+ author=['Apache Thrift Developers'],
author_email=['dev@thrift.apache.org'],
url='http://thrift.apache.org',
license='Apache License 2.0',
@@ -37,7 +37,7 @@
'fb303_scripts',
],
classifiers=[
- 'Development Status :: 5 - Production/Stable',
+ 'Development Status :: 7 - Inactive',
'Environment :: Console',
'Intended Audience :: Developers',
'Programming Language :: Python',
diff --git a/contrib/thrift-maven-plugin/pom.xml b/contrib/thrift-maven-plugin/pom.xml
index 62c2ebe..b65f6aa 100644
--- a/contrib/thrift-maven-plugin/pom.xml
+++ b/contrib/thrift-maven-plugin/pom.xml
@@ -7,9 +7,9 @@
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
@@ -17,8 +17,8 @@
specific language governing permissions and limitations
under the License.
-->
-<project
- xmlns="http://maven.apache.org/POM/4.0.0"
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
@@ -27,15 +27,15 @@
<artifactId>thrift-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<name>thrift-maven-plugin</name>
- <version>0.12.1</version>
+ <version>1.0.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
- <source>1.7</source>
- <target>1.7</target>
+ <source>1.8</source>
+ <target>1.8</target>
</configuration>
</plugin>
<plugin>
diff --git a/contrib/thrift.spec b/contrib/thrift.spec
index b777cb9..cbb08fb 100644
--- a/contrib/thrift.spec
+++ b/contrib/thrift.spec
@@ -28,7 +28,7 @@
License: Apache License v2.0
Group: Development
Summary: RPC and serialization framework
-Version: 0.12.1
+Version: 0.13.0
Release: 0
URL: http://thrift.apache.org
Packager: Thrift Developers <dev@thrift.apache.org>
@@ -58,8 +58,8 @@
Thrift is a software framework for scalable cross-language services
development. It combines a powerful software stack with a code generation
engine to build services that work efficiently and seamlessly between C++,
-Java, C#, Python, Ruby, Perl, PHP, Objective C/Cocoa, Smalltalk, Erlang,
-Objective Caml, and Haskell.
+Java, C#, Python, Ruby, Perl, PHP, Smalltalk, Erlang, OCaml, Haskell, and
+other languages.
%files
%defattr(-,root,root)
@@ -178,6 +178,19 @@
--without-csharp \
--without-erlang \
+%if 0%{!?without_ruby:1}
+eval $(grep "^WITH_RUBY_TRUE" config.log)
+if [[ "${WITH_RUBY_TRUE}" != "" ]]; then
+ set +x
+ echo ""
+ echo "configure determined that ruby requirements are missing (bundler gem?), either install missing components" >&2
+ echo "or disable the ruby sub-packages as follows:" >&2
+ echo " rpmbuild -D'%without_ruby 1' ..." >&2
+ echo ""
+ exit 1
+fi
+%endif
+
make %{?_smp_mflags}
%if 0%{!?without_java:1}
@@ -234,5 +247,7 @@
/sbin/ldconfig > /dev/null 2>&1
%changelog
+* Wed Aug 21 2013 Thrift Dev <dev@thrift.apache.org>
+- Thrift 0.9.1 release.
* Wed Oct 10 2012 Thrift Dev <dev@thrift.apache.org>
- Thrift 0.9.0 release.
diff --git a/contrib/transport-sample/ThriftCommon.h b/contrib/transport-sample/ThriftCommon.h
index d24d1a7..078ad44 100644
--- a/contrib/transport-sample/ThriftCommon.h
+++ b/contrib/transport-sample/ThriftCommon.h
@@ -16,8 +16,6 @@
//
#ifdef _WIN32 //thrift is crashing when using boost threads on Mac OSX
-# define USE_BOOST_THREAD 1
-# include <boost/thread.hpp>
#else
# include <sys/socket.h>
# include <netinet/in.h>
@@ -27,7 +25,7 @@
// Required Includes
//'server' side #includes
#include <thrift/concurrency/ThreadManager.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/server/TThreadPoolServer.h>
#include <thrift/server/TSimpleServer.h>
//'client' side #includes
@@ -89,7 +87,7 @@
else
{ //Multi-threaded server
boost::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(NumThreads);
- boost::shared_ptr<PlatformThreadFactory> threadFactory = boost::shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory());
+ boost::shared_ptr<ThreadFactory> threadFactory = boost::shared_ptr<ThreadFactory>(new ThreadFactory());
threadManager->threadFactory(threadFactory);
threadManager->start();
server.reset(new TThreadPoolServer(processor, transport, tfactory, pfactory, threadManager));
diff --git a/contrib/vagrant/centos-6.5/README.md b/contrib/vagrant/centos-6.5/README.md
index 6c24c52..55583f9 100644
--- a/contrib/vagrant/centos-6.5/README.md
+++ b/contrib/vagrant/centos-6.5/README.md
@@ -11,7 +11,7 @@
$ vagrant ssh
[vagrant@thrift ~]$ cd /thrift
[vagrant@thrift thrift]$ compiler/cpp/thrift --version
- Thrift version 0.12.1
+ Thrift version <version>
The provisioning script (inside the Vagrantfile) runs ./bootstrap.sh, ./configure, make and make check, but does not install thrift. To install thrift run "make install".
diff --git a/contrib/vagrant/centos-6.5/Vagrantfile b/contrib/vagrant/centos-6.5/Vagrantfile
index 6207958..51a2239 100644
--- a/contrib/vagrant/centos-6.5/Vagrantfile
+++ b/contrib/vagrant/centos-6.5/Vagrantfile
@@ -87,7 +87,7 @@
# Java LIB Dependencies
#####################################
-sudo yum install -y ant junit ant-nodeps ant-junit java-1.7.0-openjdk-devel
+sudo yum install -y ant junit ant-nodeps ant-junit java-1.8.0-openjdk-devel
# Python LIB Dependencies
#####################################
diff --git a/contrib/zeromq/TZmqServer.cpp b/contrib/zeromq/TZmqServer.cpp
index 4df6c92..88660a3 100644
--- a/contrib/zeromq/TZmqServer.cpp
+++ b/contrib/zeromq/TZmqServer.cpp
@@ -21,7 +21,7 @@
#include <thrift/transport/TBufferTransports.h>
#include <boost/scoped_ptr.hpp>
-using apache::thrift::stdcxx::shared_ptr;
+using apache::thrift::std::shared_ptr;
using apache::thrift::transport::TMemoryBuffer;
using apache::thrift::protocol::TProtocol;
diff --git a/contrib/zeromq/TZmqServer.h b/contrib/zeromq/TZmqServer.h
index 43f86c0..ecd13b4 100644
--- a/contrib/zeromq/TZmqServer.h
+++ b/contrib/zeromq/TZmqServer.h
@@ -20,6 +20,7 @@
#ifndef _THRIFT_SERVER_TZMQSERVER_H_
#define _THRIFT_SERVER_TZMQSERVER_H_ 1
+#include <memory>
#include <zmq.hpp>
#include <thrift/server/TServer.h>
@@ -28,7 +29,7 @@
class TZmqServer : public TServer {
public:
TZmqServer(
- apache::thrift::stdcxx::shared_ptr<TProcessor> processor,
+ std::shared_ptr<TProcessor> processor,
zmq::context_t& ctx, const std::string& endpoint, int type)
: TServer(processor)
, processor_(processor)
@@ -56,7 +57,7 @@
}
private:
- apache::thrift::stdcxx::shared_ptr<TProcessor> processor_;
+ std::shared_ptr<TProcessor> processor_;
int zmq_type_;
zmq::socket_t sock_;
};
diff --git a/contrib/zeromq/csharp/ThriftZMQ.csproj b/contrib/zeromq/csharp/ThriftZMQ.csproj
index 02a1188..80ad1db 100755
--- a/contrib/zeromq/csharp/ThriftZMQ.csproj
+++ b/contrib/zeromq/csharp/ThriftZMQ.csproj
@@ -25,7 +25,7 @@
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>0.12.1</ApplicationVersion>
+ <ApplicationVersion>1.0.0.0</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
diff --git a/contrib/zeromq/test-client.cpp b/contrib/zeromq/test-client.cpp
index 70a331e..159c250 100644
--- a/contrib/zeromq/test-client.cpp
+++ b/contrib/zeromq/test-client.cpp
@@ -6,7 +6,7 @@
#include "TZmqClient.h"
#include "Storage.h"
-using apache::thrift::stdcxx::shared_ptr;
+using apache::thrift::std::shared_ptr;
using apache::thrift::transport::TZmqClient;
using apache::thrift::protocol::TBinaryProtocol;
diff --git a/contrib/zeromq/test-receiver.cpp b/contrib/zeromq/test-receiver.cpp
index 60791ac..d465bff 100644
--- a/contrib/zeromq/test-receiver.cpp
+++ b/contrib/zeromq/test-receiver.cpp
@@ -2,7 +2,7 @@
#include "TZmqServer.h"
#include "Storage.h"
-using apache::thrift::stdcxx::shared_ptr;
+using apache::thrift::std::shared_ptr;
using apache::thrift::TProcessor;
using apache::thrift::server::TZmqServer;
using apache::thrift::server::TZmqMultiServer;
diff --git a/contrib/zeromq/test-sender.cpp b/contrib/zeromq/test-sender.cpp
index 8928db3..5c086a1 100644
--- a/contrib/zeromq/test-sender.cpp
+++ b/contrib/zeromq/test-sender.cpp
@@ -6,7 +6,7 @@
#include "TZmqClient.h"
#include "Storage.h"
-using apache::thrift::stdcxx::shared_ptr;
+using apache::thrift::std::shared_ptr;
using apache::thrift::transport::TZmqClient;
using apache::thrift::protocol::TBinaryProtocol;
diff --git a/contrib/zeromq/test-server.cpp b/contrib/zeromq/test-server.cpp
index baa1451..e6f1b20 100644
--- a/contrib/zeromq/test-server.cpp
+++ b/contrib/zeromq/test-server.cpp
@@ -2,7 +2,7 @@
#include "TZmqServer.h"
#include "Storage.h"
-using apache::thrift::stdcxx::shared_ptr;
+using apache::thrift::std::shared_ptr;
using apache::thrift::TProcessor;
using apache::thrift::server::TZmqServer;
using apache::thrift::server::TZmqMultiServer;
diff --git a/debian/changelog b/debian/changelog
index 944e935..69b5f20 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,14 +1,8 @@
-thrift (0.12.1) stable; urgency=low
-
- * update to 0.12.1
-
- -- Jens Geyer <jensg@apache.org> Mon, 25 Feb 2019 22:42:00 +0100
-
thrift (0.12.0) stable; urgency=low
* update to 0.12.0
- -- Jake Farrell <jfarrell@apache.org> Wed, 15 Oct 2018 12:00:00 -0500
+ -- Apache Thrift Developers <dev@thrift.apache.org> Wed, 28 Dec 2018 12:00:00 -0500
thrift (0.11.0) stable; urgency=low
diff --git a/debian/control b/debian/control
index cb8a376..414a815 100644
--- a/debian/control
+++ b/debian/control
@@ -3,16 +3,16 @@
Priority: extra
Build-Depends: debhelper (>= 9), build-essential, mono-mcs, python-dev, ant,
mono-devel, libmono-system-web4.0-cil, erlang-base, ruby-dev | ruby1.9.1-dev, ruby-bundler ,autoconf, automake,
- pkg-config, libtool, bison, flex, libboost-dev | libboost1.53-dev | libboost1.63-all-dev,
+ pkg-config, libtool, bison, flex, libboost-dev | libboost1.56-dev | libboost1.63-all-dev,
python-all, python-setuptools, python-all-dev, python-all-dbg,
python3-all, python3-setuptools, python3-all-dev, python3-all-dbg,
- openjdk-7-jdk | openjdk-8-jdk | default-jdk,
- libboost-test-dev | libboost-test1.53-dev | libboost-test1.63-dev, libevent-dev, libssl-dev, perl (>= 5.8.0-7),
+ openjdk-8-jdk | openjdk-8-jdk-headless | openjdk-11-jdk | openjdk-11-jdk-headless | default-jdk,
+ libboost-test-dev | libboost-test1.56-dev | libboost-test1.63-dev, libevent-dev, libssl-dev, perl (>= 5.8.0-7),
php (>= 5), php-dev (>= 5), libglib2.0-dev, qtchooser, qtbase5-dev-tools
Maintainer: Thrift Developer's <dev@thrift.apache.org>
Homepage: http://thrift.apache.org/
-Vcs-Git: https://git-wip-us.apache.org/repos/asf/thrift.git
-Vcs-Browser: https://git-wip-us.apache.org/repos/asf?p=thrift.git
+Vcs-Git: https://github.com/apache/thrift.git
+Vcs-Browser: https://github.com/apache/thrift
Standards-Version: 3.9.7
X-Python-Version: >= 2.6
X-Python3-Version: >= 3.3
diff --git a/debian/copyright b/debian/copyright
index 850643c..3e6fcf7 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -28,7 +28,6 @@
under the Apache 2.0 License:
compiler/cpp/Makefile.am
- compiler/cpp/src/generate/t_cocoa_generator.cc
compiler/cpp/src/generate/t_cpp_generator.cc
compiler/cpp/src/generate/t_csharp_generator.cc
compiler/cpp/src/generate/t_erl_generator.cc
diff --git a/debian/rules b/debian/rules
index 9b436d9..e209ba3 100755
--- a/debian/rules
+++ b/debian/rules
@@ -96,8 +96,6 @@
# Add here commands to clean up after the build process.
-$(MAKE) clean
- $(CURDIR)/cleanup.sh
-
dh_clean
install: install-indep install-arch
diff --git a/doap.rdf b/doap.rdf
index 12fb5f0..50b3491 100755
--- a/doap.rdf
+++ b/doap.rdf
@@ -27,7 +27,7 @@
<name>Apache Thrift</name>
<homepage rdf:resource="http://thrift.apache.org" />
<asfext:pmc rdf:resource="http://thrift.apache.org" />
- <shortdesc>Apache Thrift software provides a framework for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages. </shortdesc>
+ <shortdesc>Apache Thrift software provides a framework for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages. </shortdesc>
<description>Apache Thrift allows you to define data types and service interfaces in a simple definition file. Taking that file as input, the compiler generates code to be used to easily build RPC clients and servers that communicate seamlessly across programming languages. Instead of writing a load of boilerplate code to serialize and transport your objects and invoke remote methods, you can get right down to business. </description>
<bug-database rdf:resource="https://issues.apache.org/jira/browse/THRIFT" />
<mailing-list rdf:resource="http://thrift.apache.org/mailing/" />
@@ -36,7 +36,6 @@
<programming-language>C</programming-language>
<programming-language>C#</programming-language>
<programming-language>C++</programming-language>
- <programming-language>Cocoa</programming-language>
<programming-language>D</programming-language>
<programming-language>Dart</programming-language>
<programming-language>Delphi</programming-language>
@@ -60,12 +59,7 @@
<release rdf:parseType="Collection">
<Version>
<name>Apache Thrift</name>
- <created>2019-02-25</created>
- <revision>0.12.1</revision>
- </Version>
- <Version>
- <name>Apache Thrift</name>
- <created>2018-10-15</created>
+ <created>2018-12-28</created>
<revision>0.12.0</revision>
</Version>
<Version>
@@ -141,8 +135,8 @@
</release>
<repository>
<GitRepository>
- <location rdf:resource="https://git-wip-us.apache.org/repos/asf/thrift.git"/>
- <browse rdf:resource="https://git-wip-us.apache.org/repos/asf?p=thrift.git"/>
+ <location rdf:resource="https://github.com/apache/thrift.git"/>
+ <browse rdf:resource="https://github.com/apache/thrift"/>
</GitRepository>
</repository>
<maintainer>
diff --git a/doc/ReleaseManagement.md b/doc/ReleaseManagement.md
new file mode 100644
index 0000000..ce0744b
--- /dev/null
+++ b/doc/ReleaseManagement.md
@@ -0,0 +1,418 @@
+# Apache Thrift Release Management
+
+Instructions for preparing and distributing a release of Apache Thrift are fairly complex. These procedures are documented here, and we're working to automate as much of this as possible. There are few projects like ours that integrate with 28 programming languages. Given the extreme number of package management systems that Apache Thrift integrates with (compared to perhaps any), part of the burden of releasing Apache Thrift is to manually package and upload some of these [language-specific packages](http://apache.thrift.org/libraries).
+
+It is important to note here that Apache Thrift is designed for version interoperability, so one can use a version 0.7.0 client with a 0.12.0 server. A particular version number does not make any guarantees as to the features available in any given language. See the [Language Feature Matrix](https://github.com/apache/thrift/blob/master/LANGUAGES.md) to learn more.
+
+## Concepts
+
+### Versioning
+
+Apache Thrift and the vast majority of package management systems out there conform to the [SemVer 2.0](https://semver.org/spec/v2.0.0.html) version numbering specification.
+
+In terms of releases, the important version numbers for Apache Thrift are the major and minor. The patch number is used in the following cases:
+
+1. There were language-specific critical defects or packaging issues.
+1. There was something horribly and fundamentally wrong with a x.x.0 release.
+
+#### External Package Patches
+
+It is common to have language-specific critical defects or packaging errors that need to be resolved between releases of Apache Thrift. The project handles these on a case-by-case basis for languages that have their own [package management systems](http://apache.thrift.org/libraries). When a language-specific patch is made, the patch level of the distribution pushed to the external package manager is bumped.
+
+ As such, there may be cases between Apache Thrift releases where there are (for example) a `0.12.1` and `0.12.2` version of a Haskell Hackage package, and perhaps also a `0.12.3` version of a dlang dub package. You will not find a tag or an official project release in these cases, however the code changes will be reflected in the release branch and in master. In these cases we would not release a version of Apache Thrift nor would we refresh all the external language packages.
+
+#### Version in the master branch
+
+The master branch will always contain the next anticipated release version. When a release cycle begins, a branch is cut from master. The release branch will already have all of the correct versions, and therefore release branches can be easily merged back into master. (This was not true of releases before 0.12.0).
+
+### Code Repository
+
+The authoritative repository for Apache Thrift is stored in [GitHub](https://github.com/apache/thrift). It is mirrored by [GitBox](https://gitbox.apache.org/repos/asf?p=thrift.git).
+
+### Branches
+
+All code (submitted via pull request or direct push) is committed to the `master` branch. Until version 1.0 of Apache Thrift each release branch was named `<version>`, for example in version `0.12.0` there is a branch named the same. For version 1.0 releases any beyond, releases will have a branch named `release/<version>`.
+
+### Tags
+
+Up to version `0.12.0` each release of Apache Thrift was tagged with a `<version>` tag. Starting with the `0.12.0` release, each release of Apache Thrift will be tagged with a `v<version>` tag to satisfy external package management tools (such as ones for dlang and golang). For example the tag of version `0.12.0` is `v0.12.0`.
+
+## Release Procedures
+
+### Release Schedule
+
+Apache Thrift has no official release schedule, however the project aims to release at least twice per year.
+
+A complete release cycle will take about 1 week to complete, if things go well, with half of that time waiting for a vote.
+
+### Release Manager
+
+Before a release cycle begins, someone must nominate themselves on the development mailing list as the release manager for that release. In order to be a release manager you must meet the following criteria:
+
+1. You are a [member](http://people.apache.org/phonebook.html?pmc=thrift) of the Apache PMC group.
+1. Your profile at https://id.apache.org/ is valid and contains a PGP key. If it does not, see the [Apache OpenPGP Instructions](https://www.apache.org/dev/openpgp.html). If your PGP private key creation seems to hang indefinitely while creating entropy, try these fixes:
+ - Generate disk I/O with: `dd if=/dev/sda of=/dev/zero`
+ - Install the `rng-tools` package.
+1. Your PGP key is visible in the [Apache Committer Keys](http://people.apache.org/keys/committer/) for code signing. This list is updated periodically from your Apache ID (see previous step).
+1. You have read and agree with the contents of the [ASF Release Distribution Policy](https://www.apache.org/dev/release-distribution.html).
+1. You have access and the ability to use subversion. All distribution artifacts are released through a subversion commit.
+1. You can build in the Linux Docker Container, and you have Visual Studio 2017.
+1. You have sufficient time to complete a release distribution.
+
+### Release Candidate
+
+All Apache Thrift releases go through a 72-hour final release candidate voting procedure. Votes from members of the Apache Thrift PMC are binding, and all others are non-binding. For these examples, the `master` branch is at version 1.0.0 and that is the next release.
+
+1. Scrub the Apache Jira backlog. There are a couple things to do:
+
+ 1. [Open Issues without a Component](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20status%20!%3D%20Closed%20and%20component%20is%20empty) - make sure everything has an assigned component, as the release notes are grouped together by language.
+
+ 1. [Open Issues with a Fix Version](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20status%20in%20(OPEN%2C%20%27IN%20PROGRESS%27%2C%20REOPENED)%20and%20fixVersion%20is%20not%20empty) - these will be issues that someone placed a fixVersion on in Jira, but have not been resolved or closed yet. They are likely stale somehow. Resolutions for these issues include resolving or closing the issue in Jira, or simply removing the fixVersion if the issue hasn't been fixed.
+
+ 1. [Open Blocking Issues](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20priority%20in%20(blocker)%20and%20status%20not%20in%20(closed)%20order%20by%20component%20ASC) - blocking issues should block a release. Scrub the list to see if they are really blocking the release, and if not change their priority.
+
+ 1. [Open Critical Issues](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20priority%20in%20(critical)%20and%20status%20not%20in%20(closed)%20and%20type%20not%20in%20(%22wish%22)%20order%20by%20component%20ASC) - this list will end up in the known critical issues list in the changes file. Scrub it to make sure everything is actually critical.
+
+ It is healthy to scrub these periodically, whether or not you are making a new release.
+
+1. Check that the version number in the `master` branch matches the version number of the upcomning release. To check the `master` branch version, run:
+
+ ```bash
+ thrift$ grep AC_INIT configure.ac | cut -d'[' -f3 | cut -d']' -f1
+ 1.0.0
+ ```
+
+ If it does not match (this should be extremely rare), you need to submit a pull request setting the `master` branch to the desired version of the upcoming release. In the following example, we prepare to commit a branch where the version number is changed from `1.0.0` to `1.1.0`:
+
+ ```bash
+ thrift$ git checkout -b fix-version-for-release
+ thrift$ build/veralign.sh 1.0.0 1.1.0
+ # check to see if any of the manually modified files needs changes
+ thrift$ git push ... # make a pull request
+ ```
+
+1. Create a release branch for the release, in this example `1.0.0`:
+
+ ```bash
+ thrift$ git checkout master
+ thrift$ git pull
+ thrift$ git checkout -b "release/1.0.0"
+ thrift$ git push
+ ```
+
+ Now there is a `release/1.0.0` branch in GitHub for Apache Thrift.
+
+ By creating a release branch we allow work to continue on the `master` branch for the next release while we finalize this one. Note that `release/1.0.0` and `master` in this example are now identical, and therefore it is possible to merge the release branch back into `master` at the end of the release!
+
+1. Modify these files manually, inserting the release into them at the appropriate location. Follow existing patterns in each file:
+ - `doap.rdf`
+ - `debian/changelog`
+
+1. Generate the content for `CHANGES.md` - this is one of the most time-consuming parts of the release cycle. It is a lot of work, but the result is well worth it to the consumers of Apache Thrift:
+
+ 1. Find all [Issues Fixed but not Closed in 1.0.0](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20thrift%20and%20fixVersion%20%3D%201.0.0%20and%20status%20!%3D%20closed) (adjust the version in the link to suit your needs).
+
+ 1. Export the list of issues to a CSV (Current Fields) and open in Excel (or a similar spreadsheet).
+
+ 1. Hide all columns except for the issue id (i.e. THRIFT-nnnn), the component (first one), and the summary.
+
+ 1. Sort by component ascending and then by id ascending.
+
+ 1. Create a fourth column that will contain the contents of each line that goes into the release notes. Once you have the formula working in one cell paste it into the other rows to populate them. Use a formula to get the column to look like this:
+
+ ```vcol
+ Issue Component Summary RelNote
+ THRIFT-123 C++ - Library Drop C++03 [THRIFT-123](https://issues.apache.org/jira/browse/THRIFT-3978) - Drop C++03
+ ```
+
+ For example, if the row above was row "B" in EXCEL it would look something like:
+
+ ```text
+ =CONCAT("[", B1, "]",
+ "https://issues.apache.org/jira/browse/",
+ B1, " - ", B3)
+ ```
+
+ 1. Create a level 3 section in `CHANGES.md` under the release for each component and copy the items from the RelNote column into the changes file.
+
+ 1. Find all [Open Critical Issues](https://issues.apache.org/jira/issues/?filter=-1&jql=project%20%3D%20THRIFT%20and%20priority%20in%20(critical)%20and%20status%20not%20in%20(closed)%20and%20type%20not%20in%20(%22wish%22)%20order%20by%20component%20ASC) and add them to `CHANGES.md` in the list of known critical issues for the release.
+
+1. Commit all changes to the release branch.
+
+1. Generate the source tarball.
+
+ 1. On a linux system get a clean copy of the release branch, for example:
+
+ ```bash
+ ~$ git clone -b "release/1.0.0" git@github.com:apache/thrift.git thrift-1.0.0-src
+ ```
+
+ 1. In the clean copy of the release branch, start a docker build container and run `make dist`:
+
+ ```code
+ ~$ cd thrift-1.0.0-src
+ ~/thrift-1.0.0-src$ docker run -v $(pwd):/thrift/src:rw \
+ -it thrift/thrift-build:ubuntu-bionic /bin/bash
+ root@8b4101188aa2:/thrift/src# ./bootstrap.sh && ./configure && make dist
+ ```
+
+ The result will be a file named `thrift-1.0.0.tar.gz`. Check the size and make sure it is roughly 4MB. It could get larger over time, but it shouldn't jump by orders of magnitude. Once satisfied you can exit the docker container with `exit`.
+
+ 1. Generate signatures and checksums for the tarball:
+
+ ```bash
+ gpg --armor --output thrift-1.0.0.tar.gz.asc --detach-sig thrift-1.0.0.tar.gz
+ md5sum thrift-1.0.0.tar.gz > thrift-1.0.0.tar.gz.md5
+ sha1sum thrift-1.0.0.tar.gz > thrift-1.0.0.tar.gz.sha1
+ sha256sum thrift-1.0.0.tar.gz > thrift-1.0.0.tar.gz.sha256
+
+1. Generate the Windows Thrift Compiler. This is a statically linked compiler that is portable and folks find it useful to be able to download one, especially if they are using third-party distributed runtime libraries for interpreted languages on Windows. There are two ways to generate this:
+
+ - Using a Development VM
+
+ 1. On a Windows machine with Visual Studio, pull down the source code and checkout the release branch.
+ 1. Open an x64 Native Tools Command Prompt for VS 2017 and create an out-of-tree build directory.
+ 1. Install the latest version of cmake.
+ 1. Install chocolatey and install winflexbison with chocolatey.
+ 1. Run cmake to generate an out-of-tree build environment:
+ ```cmd
+ C:\build> cmake ..\thrift -DBISON_EXECUTABLE=c:\ProgramData\chocolatey\lib\winflexbison\tools\win_bison.exe -DFLEX_EXECUTABLE=c:\ProgramData\chocolatey\lib\winflexbison\tools\win_flex.exe -DWITH_MT=ON -DWITH_SHARED_LIB=OFF -DWITH_CPP=OFF -DWITH_JAVA=OFF -DWITH_HASKELL=OFF -DWITH_PYTHON=OFF -DWITH_C_GLIB=OFF -DBUILD_TESTING=OFF -DBUILD_TUTORIALS=OFF -DBUILD_COMPILER=ON
+ C:\build> cmake --build . --config Release
+ ```
+
+ - Using [Docker for Windows](../build/docker/msvc2017/README.md), follow the instructions for building the compiler.
+ - In both cases:
+ 1. Verify the executable only depends on kernel32.dll using [depends.exe](http://www.dependencywalker.com/).
+ 1. Copy the executable `thrift.exe` to your linux system where the signed tarball lives and rename it to `thrift-1.0.0.exe` (substitute the correct version, of course).
+ 1. Sign the executable the same way you signed the tarball.
+
+1. Upload the release artifacts to the Apache Dist/Dev site. This requires subversion:
+
+ ```bash
+ ~$ mkdir -p dist/dev
+ ~$ cd dist/dev
+ ~/dist/dev$ svn co "https://dist.apache.org/repos/dist/dev/thrift" thrift
+ ~/dist/dev$ cd thrift
+ ```
+
+ Copy the tarball, windows compiler executable, and 8 additional signing files into a new directory for the release:
+
+ ``` bash
+ ~/dist/dev/thrift$ mkdir 1.0.0-rc0
+ # copy the files into the directory
+ ~/dist/dev/thrift$ svn add 1.0.0-rc0
+ ```
+
+ The layout of the files should match the [current release](https://www.apache.org/dist/thrift/). Once done, add the release candidate and check it in:
+
+ ```bash
+ ~/dist/dev/thrift$ svn status
+ # verify everything is correct
+ ~/dist/dev/thrift$ svn commit -m "Apache Thrift 1.0.0-rc0 in dist dev" \
+ --username <apache-username> --password <apache-password>
+ ```
+
+1. Verify the release candidate artifacts are available at:
+
+ [https://dist.apache.org/repos/dist/dev/thrift/](https://dist.apache.org/repos/dist/dev/thrift/)
+
+1. Send a voting announcement message to `dev@thrift.apache.org` following this template as a guide:
+
+ ```code
+ To: dev@thrift.apache.org
+ Subject: [VOTE] Apache Thrift 1.0.0-rc0 release candidate
+ ---
+ All,
+
+ I propose that we accept the following release candidate as the official Apache Thrift 1.0.0 release:
+
+ https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.tar.gz
+
+ The release candidate was created from the release/1.0.0 branch and can be cloned using:
+
+ git clone -b release/1.0.0 https://github.com/apache/thrift.git
+
+ The release candidates GPG signature can be found at:
+ https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.tar.gz.asc
+
+ The release candidates checksums are:
+ md5:
+ sha1:
+ sha256:
+
+
+ A prebuilt statically-linked Windows compiler is available at:
+ https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.exe
+
+ Prebuilt statically-linked Windows compiler GPG signature:
+ https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.exe.asc
+
+ Prebuilt statically-linked Windows compiler checksums are:
+ md5:
+ sha1:
+ sha256:
+
+
+ The source tree as ZIP file to be published via Github releases:
+ https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.zip
+
+ ZIP source tree GPG signature:
+ https://dist.apache.org/repos/dist/dev/thrift/1.0.0-rc0/thrift-1.0.0-rc0.zip.asc
+
+ ZIP source tree checksums are:
+ md5:
+ sha1:
+ sha256:
+
+ The CHANGES list for this release is available at:
+ https://github.com/apache/thrift/blob/release/1.0.0/CHANGES.md
+
+
+ Please download, verify sig/sum, install and test the libraries and languages of your choice.
+
+ This vote will close in 72 hours on 2019-07-06 21:00 UTC
+
+ [ ] +1 Release this as Apache Thrift 1.0.0
+ [ ] +0
+ [ ] -1 Do not release this as Apache Thrift 1.0.0 because...
+ ```
+
+1. If any issues are brought up with the release candidate, you will need to package another and reset the voting clock.
+
+Voting on the development mailing list provides additional benefits (wisdom from [Christopher Tubbs](https://issues.apache.org/jira/browse/THRIFT-4506?focusedCommentId=16791902&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-16791902)):
+- It creates a public record for the vote,
+- It allows for participation/evaluation from our wider user audience (more diversity in evaluators improves quality), and
+- It provides more entry points for potential future committers/PMC members to earn merit through participation.
+
+### Official Release
+
+1. Send a message to `dev@thrift.apache.org` with the voting results. Use this template as a guide:
+
+ ```code
+ To: dev~thrift.apache.org
+ Subject: [VOTE][RESULT] Release Apache Thrift 1.0.0
+ ---
+ All,
+
+ Including my own vote of +1 we have N binding +1 and no -1.
+ The vote for the Apache Thrift 1.0.0 release is ***successful***.
+ Thank you to all who helped test and verify.
+ ```
+
+1. Use svn to checkout the release part of thrift (similar to dev) and copy the files over from dev, matching the previous release structure:
+
+ ```bash
+ ~$ mkdir -p dist/release
+ ~$ cd dist/release
+ ~/dist/release$ svn co "https://dist.apache.org/repos/dist/release/thrift" thrift
+ ~/dist/release$ cd thrift
+ ~/dist/release/thrift$ mkdir 1.0.0
+ ~/dist/release/thrift$ cp -p ../../dev/thrift/1.0.0-rc0/* 1.0.0/
+ ~/dist/release/thrift$ svn status
+ # verify everything is correct
+ ~/dist/release/thrift$ svn commit -m "Apache Thrift 1.0.0 official release" \
+ --username <apache-username> --password <apache-password>
+ ```
+
+ **NOTE** One you check in, you need to wait about a day for all the mirrors to update. You cannot send the announcement email or update the web site until the mirrors are updated.
+
+1. Create and push a tag for the release, for example "v1.0.0".
+
+ **NOTE:** All new releases must have the "v" prefix to satisfy third party package managers (dlang dub, golang, etc..)
+
+ **NOTE:** You **should** [sign the release tag](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work). Since you already have a GPG signing key for publishing the Apache Release, you want to [upload that key to your GitHub account](https://help.github.com/en/articles/adding-a-new-gpg-key-to-your-github-account). Once the key is known by GitHub you can sign the tag.
+
+ ```bash
+ ~/thrift$ # make sure you are on the release branch
+ ~/thrift$ git checkout release/1.0.0
+ ~/thrift$ git pull
+ ~/thrift$ git tag -s v1.0.0 -m "Version 1.0.0"
+ ~/thrift$ git push --tags
+ ```
+
+ **NOTE:** If you get the error "gpg failed to sign the data" when tagging, try this fix: "export GPG_TTY=$(tty)"
+
+1. Create a new release from the [GitHub Tags Page](https://github.com/apache/thrift/tags). Attach the statically built Windows thrift compiler as a binary here.
+
+1. Merge the release branch into master. This ensures all changes made to fix up the release are in master.
+
+ ```bash
+ ~/thrift$ git checkout master
+ ~/thrift$ git pull
+ ~/thrift$ git merge release/1.0.0
+ ```
+
+ The merge of 1.0.0 into master should proceed as a fast-forward since the 1.0.0 release branch. If there are discrepancies the best thing to do is resolve them and then submit a pull request. This pull request must be *MERGED* and not *REBASED* after the CI build is successful. You may want to do this yourself and mark the pull request as `[DO NOT MERGE]`.
+
+1. Update the ASF CMS content for thrift to include the new release. Note over time we will retire this in favor of including all documentation in the GitHub repository. The page with the variables that are important like the current release or distribution links is in trunk/lib/path.pm in the ASF CMS for thrift.
+
+ 1. Go to the [ASF CMS for Thrift](https://cms.apache.org/thrift/).
+ 1. Get a working copy.
+ 1. On the top right, click on `trunk`.
+ 1. Navigate into `lib`.
+ 1. Open `path.pm`.
+ 1. Edit
+ 1. Change `current_release` and `current_release_date` to reflect the correct information.
+ 1. Submit
+ 1. Commit
+ 1. Submit
+ 1. Follow Staging Build until it completes.
+ 1. Open the Staged site.
+ 1. Ensure the download links work.
+ 1. Publish Site.
+
+1. Make an announcement on the dev@ and user@ mailing lists of the release. There's no template to follow, but you can point folks to the official web site at https://thrift.apache.org, and to the GitHub site at https://github.org/apache.thrift.
+
+### Post-Release
+
+1. Visit https://reporter.apache.org/addrelease.html?thrift and register it. You will get an automated reminder as the one who committed into dist. This informs the Apache Board of Directors of releases through project reports.
+
+1. Create a local branch to bump the release number to the next anticipated release:
+
+ ```bash
+ ~/thrift$ git checkout -b bump-master
+ ~/thrift$ build/veralign.sh 1.0.0 1.1.0
+ ```
+
+ The veralign script will set the version number in all of the language packaging files and headers. You do not need to worry about the manually modified files at this time. You should however ensure everything is correct by looking at the diff.
+
+1. Create a pull request to advance master to the next anticipated release.
+
+1. In Apache Jira, select all tickets where the fix version is the release and the status is not closed ([example](https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20fixVersion%20%3D%201.0%20%20and%20status%20!%3D%20Closed)) and use the bulk editing tool to close them.
+1. **FIXME** Ask someone with admin access to Apache Jira to change the fixVersion in question from unreleased to released, for example:
+ https://issues.apache.org/jira/browse/THRIFT-4686
+
+1. Ensure that the [Jira release page](https://issues.apache.org/jira/projects/THRIFT?selectedItem=com.atlassian.jira.jira-projects-plugin%3Arelease-page&status=unreleased) for the version has the same number of issues in the version as issues done, and that there are no issues in progress and no issues to do, and no warnings. Finally, mark it as released and set the date of the release.
+
+* [Report any CVEs](https://apache.org/security/committers.html) that were fixed. You can email `security@apache.org` if you are not sure if there are any CVEs to report.
+
+#### Third Party Package Managers
+
+See https://thrift.apache.org/lib/ for the current status of each external package manager's distribution. Information below is from the 0.12.0 release:
+
+ > This section needs to be updated with detailed instructions for each language, or pointers to the README.md files in each language directory with detailed release instructions for the given package management system.
+
+* [dart] Releasing this requires a google account.
+ * You will need to install the same version of dart that is used in the docker image.
+ * Go into lib/dart and run "pub publish --dry-run" and resolve any warnings.
+ * Run "pub publish" and go through the google account authorization to allow it.
+* [dlang] Within a day, the dlang dub site https://code.dlang.org/packages/apache-thrift?tab=info
+ should pick up the release based on the tag. No action needed.
+* [haskell] https://hackage.haskell.org/package/thrift
+ https://jira.apache.org/jira/browse/THRIFT-4698
+* [npmjs] @jfarrell is the only one who can do this right now.
+ https://issues.apache.org/jira/browse/THRIFT-4688
+* [perl] A submission to CPAN is necessary (normally jeking3 does this):
+ * Checkout the release branch or tag on a linux system.
+ * Fire up the docker build container.
+ * Run "make clean" and remove any gen-perl directories.
+ * Inside `lib/perl` run the script `build-cpan-dist.sh`.
+ * Upload the resulting package. If there's a mistake that needs to be corrected,
+ increase the suffix. (_1, _2, ...) and upload another. You cannot replace a release on CPAN.
+* [php] @jfarrell, @bufferoverflow, @jeking3 are the only ones who can do this right now.
+ * Once the release is tagged, one just has to hit the "Update" button to pick it up.
+* [pypi] @jfarrell is the only one who can do this right now.
+ https://issues.apache.org/jira/browse/THRIFT-4687
+* [rust] Any thrift project committer is allowed to upload a new crate.
+
+If you have any questions email `dev@thrift.apache.org`.
diff --git a/doc/committers.md b/doc/committers.md
index b02edbe..dcdd7b7 100644
--- a/doc/committers.md
+++ b/doc/committers.md
@@ -4,7 +4,7 @@
1. Check out the latest version of the source code
- * git clone https://git-wip-us.apache.org/repos/asf/thrift.git thrift
+ * git clone https://github.com/apache/thrift.git thrift
1. Apply the patch
diff --git a/doc/install/README.md b/doc/install/README.md
index e37f4ff..e48cc4a 100644
--- a/doc/install/README.md
+++ b/doc/install/README.md
@@ -3,7 +3,7 @@
* A relatively POSIX-compliant *NIX system
* Cygwin or MinGW can be used on Windows (but there are better options, see below)
* g++ 4.2
-* boost 1.53.0
+* boost 1.56.0
* Runtime libraries for lex and yacc might be needed for the compiler.
## Requirements for building from source
@@ -23,11 +23,11 @@
These are only required if you choose to build the libraries for the given language
* C++
- * Boost 1.53.0
+ * Boost 1.56.0
* libevent (optional, to build the nonblocking server)
* zlib (optional)
* Java
- * Java 1.7
+ * Java 1.8
* Apache Ant
* C#: Mono 1.2.4 (and pkg-config to detect it) or Visual Studio 2005+
* Python 2.6 (including header files for extension modules)
diff --git a/doc/install/centos.md b/doc/install/centos.md
index 609e118..18282a3 100644
--- a/doc/install/centos.md
+++ b/doc/install/centos.md
@@ -54,17 +54,17 @@
sudo yum -y install libevent-devel zlib-devel openssl-devel
-### Upgrade Boost >= 1.53
+### Upgrade Boost >= 1.56
- wget http://sourceforge.net/projects/boost/files/boost/1.53.0/boost_1_53_0.tar.gz
- tar xvf boost_1_53_0.tar.gz
- cd boost_1_53_0
+ wget http://sourceforge.net/projects/boost/files/boost/1.56.0/boost_1_56_0.tar.gz
+ tar xvf boost_1_56_0.tar.gz
+ cd boost_1_56_0
./bootstrap.sh
sudo ./b2 install
## Build and Install the Apache Thrift IDL Compiler
- git clone https://git-wip-us.apache.org/repos/asf/thrift.git
+ git clone https://github.com/apache/thrift.git
cd thrift
./bootstrap.sh
./configure --with-lua=no
diff --git a/doc/install/debian.md b/doc/install/debian.md
index 83090ab..84f696e 100644
--- a/doc/install/debian.md
+++ b/doc/install/debian.md
@@ -19,7 +19,7 @@
* Java
* packages: ant
- * You will also need Java JDK v1.7 or higher. Type **javac** to see a list of available packages, pick the one you prefer and **apt-get install** it (e.g. default-jdk).
+ * You will also need Java JDK v1.8 or higher. Type **javac** to see a list of available packages, pick the one you prefer and **apt-get install** it (e.g. default-jdk).
* Ruby
* ruby-full ruby-dev ruby-rspec rake rubygems bundler
* Python
diff --git a/doc/install/windows.md b/doc/install/windows.md
index 7b09840..8618934 100644
--- a/doc/install/windows.md
+++ b/doc/install/windows.md
@@ -145,7 +145,7 @@
Make sure you have java in your $PATH variable, if not do(adjust path if necessary):
- export PATH=$PATH:"/cygdrive/c/program files/java/jre1.6.0_05/bin"
+ export PATH=$PATH:"/cygdrive/c/program files/java/jre1.8.0_191/bin"
Run configure - using CXXFLAGS to work around an issue with an old pthreads define (untested on MinGW - works on Cygwin):
diff --git a/doc/specs/SequenceNumbers.md b/doc/specs/SequenceNumbers.md
new file mode 100644
index 0000000..fef3fcf
--- /dev/null
+++ b/doc/specs/SequenceNumbers.md
@@ -0,0 +1,23 @@
+# Sequence Number #
+
+Apache Thrift built sequence numbers into every protocol exchange to allow
+for clients that may submit multiple outstanding requests on a single transport
+connection. This is typically done by asynchronous clients.
+
+The following rules apply to sequence numbers:
+
+1. A sequence number is a signed 32-bit integer. Negative values are allowed.
+1. Sequence numbers `MUST` be unique across all outstanding requests on a
+ given transport connection. There is no requirement for unique numbers
+ between different transport connections even if they are from the same client.
+1. A server `MUST` reply to a client with the same sequence number that was
+ used in the request. This includes any exception-based reply.
+1. A client `MAY` use sequence numbers if it needs them for proper operation.
+1. A client `SHOULD` set the sequence number to zero if it does not rely
+ on them.
+1. Wrapped protocols (such as THeaderProtocol) `SHOULD` use the same sequence
+ number on the wrapping as is used on the payload protocol.
+
+Servers will not inspect or make any logic choices based on the sequence number
+sent by the client. The server's only job is to process the request and reply
+with the same sequence number.
diff --git a/doc/specs/idl.md b/doc/specs/idl.md
index dab04c7..ac35368 100644
--- a/doc/specs/idl.md
+++ b/doc/specs/idl.md
@@ -1,10 +1,11 @@
## Thrift interface description language
+
+For Thrift version 0.13.0.
+
The Thrift interface definition language (IDL) allows for the definition of [Thrift Types](/docs/types). A Thrift IDL file is processed by the Thrift code generator to produce code for the various target languages to support the defined structs and services in the IDL file.
## Description
-*Under construction*
-
Here is a description of the Thrift IDL.
## Document
@@ -35,32 +36,9 @@
A namespace declares which namespaces/package/module/etc. the type definitions in this file will be declared in for the target languages. The namespace scope indicates which language the namespace applies to; a scope of '*' indicates that the namespace applies to all target languages.
- [5] Namespace ::= ( 'namespace' ( NamespaceScope Identifier ) |
- ( 'smalltalk.category' STIdentifier ) |
- ( 'smalltalk.prefix' Identifier ) ) |
- ( 'php_namespace' Literal ) |
- ( 'xsd_namespace' Literal )
+ [5] Namespace ::= ( 'namespace' ( NamespaceScope Identifier ) )
- [6] NamespaceScope ::= '*' | 'cpp' | 'java' | 'py' | 'perl' | 'rb' | 'cocoa' | 'csharp'
-
-N.B.: Smalltalk has two distinct types of namespace commands:
-
-- smalltalk.prefix: Prepended to generated classnames.
- - Smalltalk does not have namespaces for classes, so prefixes
- are used to avoid class-name collisions.
- Often, the prefix is the author's initials, like "KB" or "JWS",
- or an abbreviation of the package name, like "MC" for "Monticello".
-- smalltalk.category: Determines the category for generated classes.
- Any dots in the identifier will be replaced with hyphens when generating
- the category name.
- If not provided, defaults to "Generated-" + the program name.
- Methods will not be categorized beyond "as yet uncategorized".
- - Smalltalk allows filing both classes and methods within classes into named
- groups. These named groups of methods are called categories.
-
-N.B.: The `php_namespace` directive will be deprecated at some point in the future in favor of the scoped syntax, but the scoped syntax is not yet supported for PHP.
-
-N.B.: The `xsd_namespace` directive has some purpose internal to Facebook but serves no purpose in Thrift itself. Use of this feature is strongly discouraged
+ [6] NamespaceScope ::= '*' | 'c_glib' | 'cpp' | 'csharp' | 'delphi' | 'go' | 'java' | 'js' | 'lua' | 'netcore' | 'perl' | 'php' | 'py' | 'py.twisted' | 'rb' | 'st' | 'xsd'
## Definition
@@ -118,7 +96,7 @@
## Field
- [16] Field ::= FieldID? FieldReq? FieldType Identifier ('= ConstValue)? XsdFieldOptions ListSeparator?
+ [16] Field ::= FieldID? FieldReq? FieldType Identifier ('=' ConstValue)? XsdFieldOptions ListSeparator?
### Field ID
@@ -242,9 +220,9 @@
* [Apache Cassandra's][] Thrift IDL: [cassandra.thrift][]
* [Evernote API][]
- [ThriftTest.thrift]: https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob_plain;f=test/ThriftTest.thrift;hb=HEAD
+ [ThriftTest.thrift]: https://raw.githubusercontent.com/apache/thrift/master/test/ThriftTest.thrift
[tutorial]: /tutorial/
- [fb303.thrift]: https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob_plain;f=contrib/fb303/if/fb303.thrift;hb=HEAD
+ [fb303.thrift]: https://raw.githubusercontent.com/apache/thrift/master/contrib/fb303/if/fb303.thrift
[Apache Cassandra's]: http://cassandra.apache.org/
[cassandra.thrift]: http://svn.apache.org/viewvc/cassandra/trunk/interface/cassandra.thrift?view=co
[Evernote API]: http://www.evernote.com/about/developer/api/
diff --git a/dub.json b/dub.json
index 1e26860..af76afc 100644
--- a/dub.json
+++ b/dub.json
@@ -11,10 +11,10 @@
"version": "~>2.0.2"
},
"openssl": {
- "version": "~>1.1.6"
+ "version": ">=1.1.6"
}
},
- "systemDependencies": "requires openssl 1.0 until deimos module is updated",
+ "systemDependencies": "On systems with native openssl 1.0.x use dub package openssl~>1.1, on systems with native openssl 1.1.x use dub package openssl~>2.0",
"targetType": "library",
"sourcePaths": [
"lib/d/src"
diff --git a/jitpack.yml b/jitpack.yml
new file mode 100644
index 0000000..a640d5d
--- /dev/null
+++ b/jitpack.yml
@@ -0,0 +1,2 @@
+install:
+ - gradle -Prelease=true -p lib/java/ clean install
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 1a9177a..73326a5 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -25,11 +25,8 @@
endif
if WITH_CPP
-# cpp dir is picked directly by plugin build
-if !WITH_PLUGIN
SUBDIRS += cpp
endif
-endif
if WITH_C_GLIB
SUBDIRS += c_glib
@@ -75,8 +72,9 @@
SUBDIRS += dart
endif
-if WITH_DOTNETCORE
+if WITH_DOTNET
SUBDIRS += netcore
+SUBDIRS += netstd
endif
if WITH_GO
@@ -106,11 +104,14 @@
SUBDIRS += cl
endif
+if WITH_SWIFT
+SUBDIRS += swift
+endif
+
# All of the libs that don't use Automake need to go in here
# so they will end up in our release tarballs.
EXTRA_DIST = \
as3 \
- cocoa \
d \
dart \
delphi \
diff --git a/lib/as3/gradle.properties b/lib/as3/gradle.properties
index d746018..02d5eef 100644
--- a/lib/as3/gradle.properties
+++ b/lib/as3/gradle.properties
@@ -1,7 +1,7 @@
# This file is shared currently between this Gradle build and the
# Ant builds for fd303 and JavaScript. Keep the dotted notation for
# the properties to minimize the changes in the dependencies.
-thrift.version=0.12.1
+thrift.version=0.13.0
thrift.groupid=org.apache.thrift
release=false
sign=false
diff --git a/lib/c_glib/CMakeLists.txt b/lib/c_glib/CMakeLists.txt
index 3743a68..3e4a154 100644
--- a/lib/c_glib/CMakeLists.txt
+++ b/lib/c_glib/CMakeLists.txt
@@ -39,6 +39,7 @@
src/thrift/c_glib/protocol/thrift_protocol_decorator.c
src/thrift/c_glib/protocol/thrift_binary_protocol.c
src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
+ src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
src/thrift/c_glib/protocol/thrift_binary_protocol_factory.c
src/thrift/c_glib/protocol/thrift_compact_protocol.c
src/thrift/c_glib/protocol/thrift_compact_protocol_factory.c
@@ -60,7 +61,7 @@
# If OpenSSL is not found just ignore the OpenSSL stuff
find_package(OpenSSL)
if(OPENSSL_FOUND AND WITH_OPENSSL)
- list( APPEND thriftcpp_SOURCES
+ list( APPEND thrift_c_glib_SOURCES
src/thrift/c_glib/transport/thrift_ssl_socket.c
)
include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
diff --git a/lib/c_glib/README.md b/lib/c_glib/README.md
index 0431e18..dd84f3d 100644
--- a/lib/c_glib/README.md
+++ b/lib/c_glib/README.md
@@ -35,7 +35,7 @@
Breaking Changes
================
-0.12.x
+0.12.0
------
The compiler's handling of namespaces when generating the name of types,
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
index 727f4a8..352e301 100644
--- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_multiplexed_protocol.c
@@ -49,7 +49,6 @@
g_return_val_if_fail (THRIFT_IS_MULTIPLEXED_PROTOCOL (protocol), -1);
ThriftMultiplexedProtocol *self = THRIFT_MULTIPLEXED_PROTOCOL (protocol);
- ThriftMultiplexedProtocolClass *multiplexClass = THRIFT_MULTIPLEXED_PROTOCOL_GET_CLASS(self);
if( (message_type == T_CALL || message_type == T_ONEWAY) && self->service_name != NULL) {
service_name = g_strdup_printf("%s%s%s", self->service_name, THRIFT_MULTIPLEXED_PROTOCOL_DEFAULT_SEPARATOR, name);
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
index a0d560b..22aca8a 100644
--- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
@@ -172,7 +172,7 @@
g_param_spec_int ("seqid",
"Sequence id type in the wire",
"Set the Sequence id in the wire",
- 0, G_MAXINT,
+ G_MININT, G_MAXINT,
0,
(G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
index 6dd0f0d..560c24e 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c
@@ -163,7 +163,7 @@
/* open a connection */
if (connect (tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1)
{
- thrift_socket_close(tsocket, NULL);
+ thrift_socket_close(transport, NULL);
g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CONNECT,
"failed to connect to host %s:%d - %s",
tsocket->hostname, tsocket->port, strerror(errno));
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
index ee55406..df17fa6 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.c
@@ -369,8 +369,6 @@
thrift_ssl_socket_flush (ThriftTransport *transport, GError **error)
{
ThriftSSLSocket *ssl_socket = THRIFT_SSL_SOCKET (transport);
- gint ret = 0;
- guint sent = 0;
ThriftSocket *socket = THRIFT_SOCKET (transport);
g_return_val_if_fail (socket->sd != THRIFT_INVALID_SOCKET && ssl_socket->ssl!=NULL, FALSE);
diff --git a/lib/c_glib/test/CMakeLists.txt b/lib/c_glib/test/CMakeLists.txt
index fb3e41c..318b576 100644
--- a/lib/c_glib/test/CMakeLists.txt
+++ b/lib/c_glib/test/CMakeLists.txt
@@ -20,7 +20,7 @@
set(TEST_PREFIX "c_glib")
-include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
+# include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
#Make sure gen-cpp and gen-c_glib files can be included
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
diff --git a/lib/c_glib/test/testbufferedtransport.c b/lib/c_glib/test/testbufferedtransport.c
index c6e6b58..d01806d 100755
--- a/lib/c_glib/test/testbufferedtransport.c
+++ b/lib/c_glib/test/testbufferedtransport.c
@@ -175,11 +175,8 @@
static void
thrift_socket_server_open (const int port, int times)
{
- int bytes = 0;
ThriftServerTransport *transport = NULL;
ThriftTransport *client = NULL;
- guchar buf[10]; /* a buffer */
- guchar match[10] = TEST_DATA;
int i;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", port, NULL);
diff --git a/lib/c_glib/test/testframedtransport.c b/lib/c_glib/test/testframedtransport.c
index 45397ce..008e61e 100755
--- a/lib/c_glib/test/testframedtransport.c
+++ b/lib/c_glib/test/testframedtransport.c
@@ -249,11 +249,8 @@
static void
thrift_socket_server_open (const int port, int times)
{
- int bytes = 0;
ThriftServerTransport *transport = NULL;
ThriftTransport *client = NULL;
- guchar buf[10]; /* a buffer */
- guchar match[10] = TEST_DATA;
int i;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
diff --git a/lib/c_glib/test/testthrifttestclient.cpp b/lib/c_glib/test/testthrifttestclient.cpp
old mode 100755
new mode 100644
index 5b06883..20fbcdb
--- a/lib/c_glib/test/testthrifttestclient.cpp
+++ b/lib/c_glib/test/testthrifttestclient.cpp
@@ -25,7 +25,7 @@
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TDebugProtocol.h>
#include <thrift/server/TSimpleServer.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/transport/TServerSocket.h>
#include "ThriftTest.h"
#include "ThriftTest_types.h"
@@ -67,58 +67,58 @@
class TestHandler : public ThriftTestIf {
public:
- TestHandler() {}
+ TestHandler() = default;
- void testVoid() {
+ void testVoid() override {
cout << "[C -> C++] testVoid()" << endl;
}
- void testString(string& out, const string &thing) {
+ void testString(string& out, const string &thing) override {
cout << "[C -> C++] testString(\"" << thing << "\")" << endl;
out = thing;
}
- bool testBool(const bool thing) {
+ bool testBool(const bool thing) override {
cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << endl;
return thing;
}
- int8_t testByte(const int8_t thing) {
+ int8_t testByte(const int8_t thing) override {
cout << "[C -> C++] testByte(" << (int)thing << ")" << endl;
return thing;
}
- int32_t testI32(const int32_t thing) {
+ int32_t testI32(const int32_t thing) override {
cout << "[C -> C++] testI32(" << thing << ")" << endl;
return thing;
}
- int64_t testI64(const int64_t thing) {
+ int64_t testI64(const int64_t thing) override {
cout << "[C -> C++] testI64(" << thing << ")" << endl;
return thing;
}
- double testDouble(const double thing) {
+ double testDouble(const double thing) override {
cout.precision(6);
cout << "[C -> C++] testDouble(" << fixed << thing << ")" << endl;
return thing;
}
- void testBinary(string& out, const string &thing) {
+ void testBinary(string& out, const string &thing) override {
cout << "[C -> C++] testBinary(\"" << thing << "\")" << endl;
out = thing;
}
- void testStruct(Xtruct& out, const Xtruct &thing) {
+ void testStruct(Xtruct& out, const Xtruct &thing) override {
cout << "[C -> C++] testStruct({\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "})" << endl;
out = thing;
}
- void testNest(Xtruct2& out, const Xtruct2& nest) {
+ void testNest(Xtruct2& out, const Xtruct2& nest) override {
const Xtruct &thing = nest.struct_thing;
cout << "[C -> C++] testNest({" << (int)nest.byte_thing << ", {\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "}, " << nest.i32_thing << "})" << endl;
out = nest;
}
- void testMap(map<int32_t, int32_t> &out, const map<int32_t, int32_t> &thing) {
+ void testMap(map<int32_t, int32_t> &out, const map<int32_t, int32_t> &thing) override {
cout << "[C -> C++] testMap({";
map<int32_t, int32_t>::const_iterator m_iter;
bool first = true;
@@ -134,7 +134,7 @@
out = thing;
}
- void testStringMap(map<std::string, std::string> &out, const map<std::string, std::string> &thing) {
+ void testStringMap(map<std::string, std::string> &out, const map<std::string, std::string> &thing) override {
cout << "[C -> C++] testStringMap({";
map<std::string, std::string>::const_iterator m_iter;
bool first = true;
@@ -151,7 +151,7 @@
}
- void testSet(set<int32_t> &out, const set<int32_t> &thing) {
+ void testSet(set<int32_t> &out, const set<int32_t> &thing) override {
cout << "[C -> C++] testSet({";
set<int32_t>::const_iterator s_iter;
bool first = true;
@@ -167,7 +167,7 @@
out = thing;
}
- void testList(vector<int32_t> &out, const vector<int32_t> &thing) {
+ void testList(vector<int32_t> &out, const vector<int32_t> &thing) override {
cout << "[C -> C++] testList({";
vector<int32_t>::const_iterator l_iter;
bool first = true;
@@ -183,16 +183,16 @@
out = thing;
}
- Numberz::type testEnum(const Numberz::type thing) {
+ Numberz::type testEnum(const Numberz::type thing) override {
cout << "[C -> C++] testEnum(" << thing << ")" << endl;
return thing;
}
- UserId testTypedef(const UserId thing) {
+ UserId testTypedef(const UserId thing) override {
cout << "[C -> C++] testTypedef(" << thing << ")" << endl;
return thing; }
- void testMapMap(map<int32_t, map<int32_t,int32_t> > &mapmap, const int32_t hello) {
+ void testMapMap(map<int32_t, map<int32_t,int32_t> > &mapmap, const int32_t hello) override {
cout << "[C -> C++] testMapMap(" << hello << ")" << endl;
map<int32_t,int32_t> pos;
@@ -207,7 +207,7 @@
}
- void testInsanity(map<UserId, map<Numberz::type,Insanity> > &insane, const Insanity &argument) {
+ void testInsanity(map<UserId, map<Numberz::type,Insanity> > &insane, const Insanity &argument) override {
THRIFT_UNUSED_VARIABLE (argument);
cout << "[C -> C++] testInsanity()" << endl;
@@ -277,7 +277,7 @@
}
- void testMulti(Xtruct &hello, const int8_t arg0, const int32_t arg1, const int64_t arg2, const std::map<int16_t, std::string> &arg3, const Numberz::type arg4, const UserId arg5) {
+ void testMulti(Xtruct &hello, const int8_t arg0, const int32_t arg1, const int64_t arg2, const std::map<int16_t, std::string> &arg3, const Numberz::type arg4, const UserId arg5) override {
THRIFT_UNUSED_VARIABLE (arg3);
THRIFT_UNUSED_VARIABLE (arg4);
THRIFT_UNUSED_VARIABLE (arg5);
@@ -291,7 +291,7 @@
}
void testException(const std::string &arg)
- throw(Xception, apache::thrift::TException)
+ throw(Xception, apache::thrift::TException) override
{
cout << "[C -> C++] testException(" << arg << ")" << endl;
if (arg.compare("Xception") == 0) {
@@ -309,7 +309,7 @@
}
}
- void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) throw(Xception, Xception2) {
+ void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) throw(Xception, Xception2) override {
cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << endl;
@@ -329,7 +329,7 @@
}
}
- void testOneway(int sleepFor) {
+ void testOneway(int sleepFor) override {
cout << "testOneway(" << sleepFor << "): Sleeping..." << endl;
sleep(sleepFor);
cout << "testOneway(" << sleepFor << "): done sleeping!" << endl;
@@ -350,12 +350,12 @@
static void
test_thrift_client (void)
{
- ThriftSocket *tsocket = NULL;
- ThriftBinaryProtocol *protocol = NULL;
- TTestThriftTestClient *client = NULL;
- TTestThriftTestIf *iface = NULL;
- GError *error = NULL;
- gchar *string = NULL;
+ ThriftSocket *tsocket = nullptr;
+ ThriftBinaryProtocol *protocol = nullptr;
+ TTestThriftTestClient *client = nullptr;
+ TTestThriftTestIf *iface = nullptr;
+ GError *error = nullptr;
+ gchar *string = nullptr;
gint8 byte = 0;
gint16 i16 = 0;
gint32 i32 = 0, another_i32 = 56789;
@@ -363,18 +363,18 @@
double dbl = 0.0;
TTestXtruct *xtruct_in, *xtruct_out;
TTestXtruct2 *xtruct2_in, *xtruct2_out;
- GHashTable *map_in = NULL, *map_out = NULL;
- GHashTable *set_in = NULL, *set_out = NULL;
- GArray *list_in = NULL, *list_out = NULL;
+ GHashTable *map_in = nullptr, *map_out = nullptr;
+ GHashTable *set_in = nullptr, *set_out = nullptr;
+ GArray *list_in = nullptr, *list_out = nullptr;
TTestNumberz enum_in, enum_out;
TTestUserId user_id_in, user_id_out;
- GHashTable *insanity_in = NULL;
+ GHashTable *insanity_in = nullptr;
TTestXtruct *xtruct1, *xtruct2;
- TTestInsanity *insanity_out = NULL;
- TTestXtruct *multi_in = NULL;
- GHashTable *multi_map_out = NULL;
- TTestXception *xception = NULL;
- TTestXception2 *xception2 = NULL;
+ TTestInsanity *insanity_out = nullptr;
+ TTestXtruct *multi_in = nullptr;
+ GHashTable *multi_map_out = nullptr;
+ TTestXception *xception = nullptr;
+ TTestXception2 *xception2 = nullptr;
#if (!GLIB_CHECK_VERSION (2, 36, 0))
// initialize gobject
@@ -392,33 +392,33 @@
iface = T_TEST_THRIFT_TEST_IF (client);
// open and send
- thrift_transport_open (THRIFT_TRANSPORT(tsocket), NULL);
+ thrift_transport_open (THRIFT_TRANSPORT(tsocket), nullptr);
assert (t_test_thrift_test_client_test_void (iface, &error) == TRUE);
- assert (error == NULL);
+ assert (error == nullptr);
assert (t_test_thrift_test_client_test_string (iface, &string, "test123", &error) == TRUE);
assert (strcmp (string, "test123") == 0);
g_free (string);
- assert (error == NULL);
+ assert (error == nullptr);
assert (t_test_thrift_test_client_test_byte (iface, &byte, (gint8) 5, &error) == TRUE);
assert (byte == 5);
- assert (error == NULL);
+ assert (error == nullptr);
assert (t_test_thrift_test_client_test_i32 (iface, &i32, 123, &error) == TRUE);
assert (i32 == 123);
- assert (error == NULL);
+ assert (error == nullptr);
assert (t_test_thrift_test_client_test_i64 (iface, &i64, 12345, &error) == TRUE);
assert (i64 == 12345);
- assert (error == NULL);
+ assert (error == nullptr);
assert (t_test_thrift_test_client_test_double (iface, &dbl, 5.6, &error) == TRUE);
assert (dbl == 5.6);
- assert (error == NULL);
+ assert (error == nullptr);
- xtruct_out = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
+ xtruct_out = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
xtruct_out->byte_thing = 1;
xtruct_out->__isset_byte_thing = TRUE;
xtruct_out->i32_thing = 15;
@@ -427,50 +427,50 @@
xtruct_out->__isset_i64_thing = TRUE;
xtruct_out->string_thing = g_strdup ("abc123");
xtruct_out->__isset_string_thing = TRUE;
- xtruct_in = (TTestXtruct *) g_object_new(T_TEST_TYPE_XTRUCT, NULL);
+ xtruct_in = (TTestXtruct *) g_object_new(T_TEST_TYPE_XTRUCT, nullptr);
assert (t_test_thrift_test_client_test_struct (iface, &xtruct_in, xtruct_out, &error) == TRUE);
- assert (error == NULL);
+ assert (error == nullptr);
- xtruct2_out = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, NULL);
+ xtruct2_out = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, nullptr);
xtruct2_out->byte_thing = 1;
xtruct2_out->__isset_byte_thing = TRUE;
- if (xtruct2_out->struct_thing != NULL)
+ if (xtruct2_out->struct_thing != nullptr)
g_object_unref(xtruct2_out->struct_thing);
xtruct2_out->struct_thing = xtruct_out;
xtruct2_out->__isset_struct_thing = TRUE;
xtruct2_out->i32_thing = 123;
xtruct2_out->__isset_i32_thing = TRUE;
- xtruct2_in = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, NULL);
+ xtruct2_in = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, nullptr);
assert (t_test_thrift_test_client_test_nest (iface, &xtruct2_in, xtruct2_out, &error) == TRUE);
- assert (error == NULL);
+ assert (error == nullptr);
g_object_unref (xtruct2_out);
g_object_unref (xtruct2_in);
g_object_unref (xtruct_in);
- map_out = g_hash_table_new (NULL, NULL);
- map_in = g_hash_table_new (NULL, NULL); g_hash_table_insert (map_out, &i32, &i32);
+ map_out = g_hash_table_new (nullptr, nullptr);
+ map_in = g_hash_table_new (nullptr, nullptr); g_hash_table_insert (map_out, &i32, &i32);
assert (t_test_thrift_test_client_test_map (iface, &map_in, map_out, &error) == TRUE);
- assert (error == NULL);
+ assert (error == nullptr);
g_hash_table_destroy (map_out);
g_hash_table_destroy (map_in);
- map_out = g_hash_table_new (NULL, NULL);
- map_in = g_hash_table_new (NULL, NULL);
+ map_out = g_hash_table_new (nullptr, nullptr);
+ map_in = g_hash_table_new (nullptr, nullptr);
g_hash_table_insert (map_out, g_strdup ("a"), g_strdup ("123"));
g_hash_table_insert (map_out, g_strdup ("a b"), g_strdup ("with spaces "));
g_hash_table_insert (map_out, g_strdup ("same"), g_strdup ("same"));
g_hash_table_insert (map_out, g_strdup ("0"), g_strdup ("numeric key"));
assert (t_test_thrift_test_client_test_string_map (iface, &map_in, map_out, &error) == TRUE);
- assert (error == NULL);
+ assert (error == nullptr);
g_hash_table_destroy (map_out);
g_hash_table_destroy (map_in);
- set_out = g_hash_table_new (NULL, NULL);
- set_in = g_hash_table_new (NULL, NULL);
+ set_out = g_hash_table_new (nullptr, nullptr);
+ set_in = g_hash_table_new (nullptr, nullptr);
g_hash_table_insert (set_out, &i32, &i32);
assert (t_test_thrift_test_client_test_set (iface, &set_in, set_out, &error) == TRUE);
- assert (error == NULL);
+ assert (error == nullptr);
g_hash_table_destroy (set_out);
g_hash_table_destroy (set_in);
@@ -480,31 +480,31 @@
g_array_append_val (list_out, i32);
g_array_append_val (list_out, another_i32);
assert (t_test_thrift_test_client_test_list (iface, &list_in, list_out, &error) == TRUE);
- assert (error == NULL);
+ assert (error == nullptr);
g_array_free (list_out, TRUE);
g_array_free (list_in, TRUE);
enum_out = T_TEST_NUMBERZ_ONE;
assert (t_test_thrift_test_client_test_enum (iface, &enum_in, enum_out, &error) == TRUE);
assert (enum_in == enum_out);
- assert (error == NULL);
+ assert (error == nullptr);
user_id_out = 12345;
assert (t_test_thrift_test_client_test_typedef (iface, &user_id_in, user_id_out, &error) == TRUE);
assert (user_id_in == user_id_out);
- assert (error == NULL);
+ assert (error == nullptr);
- map_in = g_hash_table_new (NULL, NULL);
+ map_in = g_hash_table_new (nullptr, nullptr);
assert (t_test_thrift_test_client_test_map_map (iface, &map_in, i32, &error) == TRUE);
- assert (error == NULL);
+ assert (error == nullptr);
g_hash_table_destroy (map_in);
// insanity
- insanity_out = (TTestInsanity *) g_object_new (T_TEST_TYPE_INSANITY, NULL);
- insanity_out->userMap = g_hash_table_new (NULL, NULL);
+ insanity_out = (TTestInsanity *) g_object_new (T_TEST_TYPE_INSANITY, nullptr);
+ insanity_out->userMap = g_hash_table_new (nullptr, nullptr);
g_hash_table_insert (insanity_out->userMap, GINT_TO_POINTER (enum_out), &user_id_out);
- xtruct1 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
+ xtruct1 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
xtruct1->byte_thing = 1;
xtruct1->__isset_byte_thing = TRUE;
xtruct1->i32_thing = 15;
@@ -513,7 +513,7 @@
xtruct1->__isset_i64_thing = TRUE;
xtruct1->string_thing = g_strdup ("abc123");
xtruct1->__isset_string_thing = TRUE;
- xtruct2 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
+ xtruct2 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
xtruct2->byte_thing = 1;
xtruct2->__isset_byte_thing = TRUE;
xtruct2->i32_thing = 15;
@@ -523,7 +523,7 @@
xtruct2->string_thing = g_strdup ("abc123");
xtruct2->__isset_string_thing = TRUE;
- insanity_in = g_hash_table_new (NULL, NULL);
+ insanity_in = g_hash_table_new (nullptr, nullptr);
g_ptr_array_add (insanity_out->xtructs, xtruct1);
g_ptr_array_add (insanity_out->xtructs, xtruct2);
assert (t_test_thrift_test_client_test_insanity (iface, &insanity_in, insanity_out, &error) == TRUE);
@@ -531,10 +531,10 @@
g_hash_table_unref (insanity_in);
g_ptr_array_free (insanity_out->xtructs, TRUE);
- multi_map_out = g_hash_table_new (NULL, NULL);
+ multi_map_out = g_hash_table_new (nullptr, nullptr);
string = g_strdup ("abc123");
g_hash_table_insert (multi_map_out, &i16, string);
- multi_in = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
+ multi_in = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
assert (t_test_thrift_test_client_test_multi (iface, &multi_in, byte, i32, i64, multi_map_out, enum_out, user_id_out, &error) == TRUE);
assert (multi_in->i32_thing == i32);
assert (multi_in->i64_thing == i64);
@@ -545,53 +545,53 @@
assert (t_test_thrift_test_client_test_exception (iface, "Xception", &xception, &error) == FALSE);
assert (xception->errorCode == 1001);
g_error_free (error);
- error = NULL;
+ error = nullptr;
g_object_unref (xception);
- xception = NULL;
+ xception = nullptr;
assert (t_test_thrift_test_client_test_exception (iface, "ApplicationException", &xception, &error) == FALSE);
g_error_free (error);
- error = NULL;
- assert (xception == NULL);
+ error = nullptr;
+ assert (xception == nullptr);
assert (t_test_thrift_test_client_test_exception (iface, "Test", &xception, &error) == TRUE);
- assert (error == NULL);
+ assert (error == nullptr);
- multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
- assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception", NULL, &xception, &xception2, &error) == FALSE);
+ multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+ assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception", nullptr, &xception, &xception2, &error) == FALSE);
assert (xception->errorCode == 1001);
- assert (xception2 == NULL);
+ assert (xception2 == nullptr);
g_error_free (error);
- error = NULL;
+ error = nullptr;
g_object_unref (xception);
g_object_unref (multi_in);
- xception = NULL;
- multi_in = NULL;
+ xception = nullptr;
+ multi_in = nullptr;
- multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
- assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception2", NULL, &xception, &xception2, &error) == FALSE);
+ multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+ assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception2", nullptr, &xception, &xception2, &error) == FALSE);
assert (xception2->errorCode == 2002);
- assert (xception == NULL);
+ assert (xception == nullptr);
g_error_free (error);
- error = NULL;
+ error = nullptr;
g_object_unref (xception2);
g_object_unref (multi_in);
- xception2 = NULL;
- multi_in = NULL;
+ xception2 = nullptr;
+ multi_in = nullptr;
- multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, NULL);
- assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, NULL , NULL, &xception, &xception2, &error) == TRUE);
- assert (error == NULL);
+ multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+ assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, nullptr , nullptr, &xception, &xception2, &error) == TRUE);
+ assert (error == nullptr);
g_object_unref(multi_in);
- multi_in = NULL;
+ multi_in = nullptr;
assert (t_test_thrift_test_client_test_oneway (iface, 1, &error) == TRUE);
- assert (error == NULL);
+ assert (error == nullptr);
/* sleep to let the oneway call go through */
sleep (5);
- thrift_transport_close (THRIFT_TRANSPORT(tsocket), NULL);
+ thrift_transport_close (THRIFT_TRANSPORT(tsocket), nullptr);
g_object_unref (client);
g_object_unref (protocol);
g_object_unref (tsocket);
@@ -618,11 +618,11 @@
if (pid == 0) /* child */
{
- stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
- stdcxx::shared_ptr<TestHandler> testHandler(new TestHandler());
- stdcxx::shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler));
- stdcxx::shared_ptr<TServerSocket> serverSocket(new TServerSocket(TEST_PORT));
- stdcxx::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
+ std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
+ std::shared_ptr<TestHandler> testHandler(new TestHandler());
+ std::shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler));
+ std::shared_ptr<TServerSocket> serverSocket(new TServerSocket(TEST_PORT));
+ std::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
TSimpleServer simpleServer(testProcessor, serverSocket, transportFactory, protocolFactory);
signal (SIGALRM, bailout);
alarm (60);
diff --git a/lib/c_glib/test/testtransportsocket.c b/lib/c_glib/test/testtransportsocket.c
index fedbad6..89c61b9 100755
--- a/lib/c_glib/test/testtransportsocket.c
+++ b/lib/c_glib/test/testtransportsocket.c
@@ -291,11 +291,8 @@
static void
thrift_socket_server_open (const int port, int times)
{
- int bytes = 0;
ThriftServerTransport *transport = NULL;
ThriftTransport *client = NULL;
- guchar buf[10]; /* a buffer */
- guchar match[10] = TEST_DATA;
int i;
ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
"port", port, NULL);
diff --git a/lib/cocoa/README.md b/lib/cocoa/README.md
deleted file mode 100644
index bbe3c93..0000000
--- a/lib/cocoa/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-Thrift Cocoa Software Library
-
-License
-=======
-
-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.
diff --git a/lib/cocoa/coding_standards.md b/lib/cocoa/coding_standards.md
deleted file mode 100644
index fa0390b..0000000
--- a/lib/cocoa/coding_standards.md
+++ /dev/null
@@ -1 +0,0 @@
-Please follow [General Coding Standards](/doc/coding_standards.md)
diff --git a/lib/cocoa/src/TApplicationError.h b/lib/cocoa/src/TApplicationError.h
deleted file mode 100644
index 079881a..0000000
--- a/lib/cocoa/src/TApplicationError.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.
- */
-
-#import "TProtocol.h"
-
-extern NSString *TApplicationErrorDomain;
-
-typedef NS_ENUM (int, TApplicationError) {
- TApplicationErrorUnknown = 0,
- TApplicationErrorUnknownMethod = 1,
- TApplicationErrorInvalidMessageType = 2,
- TApplicationErrorWrongMethodName = 3,
- TApplicationErrorBadSequenceId = 4,
- TApplicationErrorMissingResult = 5,
- TApplicationErrorInternalError = 6,
- TApplicationErrorProtocolError = 7,
- TApplicationErrorInvalidTransform = 8,
- TApplicationErrorInvalidProtocol = 9,
- TApplicationErrorUnsupportedClientType = 10,
-};
-
-
-extern NSString *TApplicationErrorNameKey;
-extern NSString *TApplicationErrorReasonKey;
-extern NSString *TApplicationErrorMethodKey;
-
-
-@interface NSError (TApplicationError)
-
-@property (readonly, copy) NSString *name;
-@property (readonly, copy) NSString *reason;
-
-+(instancetype) errorWithType:(TApplicationError)type reason:(NSString *)reason;
-
-+(instancetype) read:(id<TProtocol>)protocol;
-
--(BOOL) write:(id<TProtocol>)outProtocol error:(NSError *__autoreleasing *)error;
-
-@end
diff --git a/lib/cocoa/src/TApplicationError.m b/lib/cocoa/src/TApplicationError.m
deleted file mode 100644
index 080bc0b..0000000
--- a/lib/cocoa/src/TApplicationError.m
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * 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.
- */
-
-#import "TApplicationError.h"
-#import "TProtocolUtil.h"
-
-
-NSString *TApplicationErrorDomain = @"TApplicationErrorDomain";
-
-
-NSString *TApplicationErrorNameKey = @"name";
-NSString *TApplicationErrorReasonKey = @"reason";
-NSString *TApplicationErrorMethodKey = @"method";
-
-
-@implementation NSError (TApplicationError)
-
--(NSString *) reason
-{
- return self.userInfo[TApplicationErrorReasonKey];
-}
-
--(NSString *) name
-{
- return self.userInfo[TApplicationErrorNameKey];
-}
-
-+(instancetype) errorWithType:(TApplicationError)type reason:(NSString *)reason
-{
- NSString *name;
- switch (type) {
- case TApplicationErrorUnknownMethod:
- name = @"Unknown Method";
- break;
-
- case TApplicationErrorInvalidMessageType:
- name = @"Invalid Message Type";
- break;
-
- case TApplicationErrorWrongMethodName:
- name = @"Wrong Method Name";
- break;
-
- case TApplicationErrorBadSequenceId:
- name = @"Bad Sequence ID";
- break;
-
- case TApplicationErrorMissingResult:
- name = @"Missing Result";
- break;
-
- case TApplicationErrorInternalError:
- name = @"Internal Error";
- break;
-
- case TApplicationErrorProtocolError:
- name = @"Protocol Error";
- break;
-
- case TApplicationErrorInvalidTransform:
- name = @"Invalid Transform";
- break;
-
- case TApplicationErrorInvalidProtocol:
- name = @"Invalid Protocol";
- break;
-
- case TApplicationErrorUnsupportedClientType:
- name = @"Unsupported Client Type";
- break;
-
- default:
- name = @"Unknown";
- break;
- }
-
- NSDictionary *userInfo;
- if (reason) {
- userInfo = @{TApplicationErrorNameKey:name,
- TApplicationErrorReasonKey:reason};
- }
- else {
- userInfo = @{TApplicationErrorNameKey:name};
- }
-
- return [NSError errorWithDomain:TApplicationErrorDomain
- code:type
- userInfo:userInfo];
-}
-
-
-+(instancetype) read:(id<TProtocol>)protocol
-{
- NSString *reason = nil;
- SInt32 type = TApplicationErrorUnknown;
- SInt32 fieldType;
- SInt32 fieldID;
-
- NSError *error;
- if (![protocol readStructBeginReturningName:NULL error:&error]) {
- return error;
- }
-
- while (true) {
-
- if (![protocol readFieldBeginReturningName:NULL
- type:&fieldType
- fieldID:&fieldID
- error:&error])
- {
- return error;
- }
-
- if (fieldType == TTypeSTOP) {
- break;
- }
-
- switch (fieldID) {
- case 1:
- if (fieldType == TTypeSTRING) {
- if (![protocol readString:&reason error:&error]) {
- return error;
- }
- }
- else {
- if (![TProtocolUtil skipType:fieldType onProtocol:protocol error:&error]) {
- return error;
- }
- }
- break;
-
- case 2:
- if (fieldType == TTypeI32) {
- if (![protocol readI32:&type error:&error]) {
- return error;
- }
- }
- else {
- if (![TProtocolUtil skipType:fieldType onProtocol:protocol error:&error]) {
- return error;
- }
- }
- break;
-
- default:
- if (![TProtocolUtil skipType:fieldType onProtocol:protocol error:&error]) {
- return error;
- }
- break;
- }
- if (![protocol readFieldEnd:&error]) {
- return error;
- }
-
- }
-
- if (![protocol readStructEnd:&error]) {
- return error;
- }
-
- return [NSError errorWithType:type reason:reason];
-}
-
-
--(BOOL) write:(id<TProtocol>)protocol error:(NSError *__autoreleasing *)error
-{
- if (![protocol writeStructBeginWithName:@"TApplicationException" error:error]) {
- return NO;
- }
-
- if (self.localizedDescription != nil) {
- if (![protocol writeFieldBeginWithName:@"message"
- type:TTypeSTRING
- fieldID:1 error:error])
- {
- return NO;
- }
-
- if (![protocol writeString:self.localizedDescription error:error]) {
- return NO;
- }
-
- if (![protocol writeFieldEnd:error]) {
- return NO;
- }
- }
-
- if (![protocol writeFieldBeginWithName:@"type"
- type:TTypeI32
- fieldID:2
- error:error])
- {
- return NO;
- }
-
- if (![protocol writeI32:(SInt32)self.code error:error]) {
- return NO;
- }
-
- if (![protocol writeFieldEnd:error]) {
- return NO;
- }
-
- if (![protocol writeFieldStop:error]) {
- return NO;
- }
-
- if (![protocol writeStructEnd:error]) {
- return NO;
- }
-
- return YES;
-}
-
-@end
diff --git a/lib/cocoa/src/TBaseClient.h b/lib/cocoa/src/TBaseClient.h
deleted file mode 100644
index 0f73aa0..0000000
--- a/lib/cocoa/src/TBaseClient.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-
-#import "TProtocol.h"
-#import "TApplicationError.h"
-
-@interface TBaseClient : NSObject
-
--(NSError *) checkIncomingMessageException:(id<TProtocol>)protocol;
-
-@end
diff --git a/lib/cocoa/src/TBaseClient.m b/lib/cocoa/src/TBaseClient.m
deleted file mode 100644
index 249cae0..0000000
--- a/lib/cocoa/src/TBaseClient.m
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.
- */
-
-#import "TBaseClient.h"
-#import "TApplicationError.h"
-
-
-@interface TBaseClient ()
-@end
-
-
-@implementation TBaseClient
-
--(NSError *) checkIncomingMessageException:(id<TProtocol>)inProtocol
-{
- NSError *thriftError;
-
- SInt32 msgType = 0;
- if (![inProtocol readMessageBeginReturningName:nil type:&msgType sequenceID:NULL error:&thriftError]) {
- return thriftError;
- }
-
- if (msgType == TMessageTypeEXCEPTION) {
-
- thriftError = [NSError read:inProtocol];
-
- [inProtocol readMessageEnd:NULL];
-
- return thriftError;
- }
-
- return nil;
-}
-
-@end
diff --git a/lib/cocoa/src/TBinary.swift b/lib/cocoa/src/TBinary.swift
deleted file mode 100644
index c8a3660..0000000
--- a/lib/cocoa/src/TBinary.swift
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.
- */
-
-import Foundation
-
-
-public struct TBinary : TSerializable {
-
- public static var thriftType : TType { return .STRING }
-
- private var storage : NSData
-
- public init() {
- self.storage = NSData()
- }
-
- public init(contentsOfFile file: String, options: NSDataReadingOptions = []) throws {
- self.storage = try NSData(contentsOfFile: file, options: options)
- }
-
- public init(contentsOfURL URL: NSURL, options: NSDataReadingOptions = []) throws {
- self.storage = try NSData(contentsOfURL: URL, options: options)
- }
-
- public init?(base64EncodedData base64Data: NSData, options: NSDataBase64DecodingOptions = []) {
- guard let storage = NSData(base64EncodedData: base64Data, options: options) else {
- return nil
- }
- self.storage = storage
- }
-
- public init(data: NSData) {
- self.storage = data
- }
-
- public var length : Int {
- return storage.length
- }
-
- public var hashValue : Int {
- return storage.hashValue
- }
-
- public var bytes : UnsafePointer<Void> {
- return storage.bytes
- }
-
- public func getBytes(buffer: UnsafeMutablePointer<Void>, length: Int) {
- storage.getBytes(buffer, length: length)
- }
-
- public func getBytes(buffer: UnsafeMutablePointer<Void>, range: Range<Int>) {
- storage.getBytes(buffer, range: NSRange(range))
- }
-
- public func subBinaryWithRange(range: Range<Int>) -> TBinary {
- return TBinary(data: storage.subdataWithRange(NSRange(range)))
- }
-
- public func writeToFile(path: String, options: NSDataWritingOptions = []) throws {
- try storage.writeToFile(path, options: options)
- }
-
- public func writeToURL(url: NSURL, options: NSDataWritingOptions = []) throws {
- try storage.writeToURL(url, options: options)
- }
-
- public func rangeOfData(dataToFind data: NSData, options: NSDataSearchOptions, range: Range<Int>) -> Range<Int>? {
- return storage.rangeOfData(data, options: options, range: NSRange(range)).toRange()
- }
-
- public func enumerateByteRangesUsingBlock(block: (UnsafePointer<Void>, Range<Int>, inout Bool) -> Void) {
- storage.enumerateByteRangesUsingBlock { bytes, range, stop in
- var stopTmp = Bool(stop.memory)
- block(bytes, range.toRange()!, &stopTmp)
- stop.memory = ObjCBool(stopTmp)
- }
- }
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> TBinary {
- var data : NSData?
- try proto.readBinary(&data)
- return TBinary(data: data!)
- }
-
- public static func writeValue(value: TBinary, toProtocol proto: TProtocol) throws {
- try proto.writeBinary(value.storage)
- }
-
-}
-
-extension TBinary : CustomStringConvertible, CustomDebugStringConvertible {
-
- public var description : String {
- return storage.description
- }
-
- public var debugDescription : String {
- return storage.debugDescription
- }
-
-}
-
-public func ==(lhs: TBinary, rhs: TBinary) -> Bool {
- return lhs.storage == rhs.storage
-}
diff --git a/lib/cocoa/src/TEnum.swift b/lib/cocoa/src/TEnum.swift
deleted file mode 100644
index 562a53a..0000000
--- a/lib/cocoa/src/TEnum.swift
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-
-import Foundation
-
-
-public protocol TEnum : TSerializable {
-
-}
-
-public extension TEnum {
-
- public static var thriftType : TType { return TType.I32 }
-
-}
diff --git a/lib/cocoa/src/TError.h b/lib/cocoa/src/TError.h
deleted file mode 100644
index abb72c7..0000000
--- a/lib/cocoa/src/TError.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-
-
-extern NSString *TErrorDomain;
diff --git a/lib/cocoa/src/TError.m b/lib/cocoa/src/TError.m
deleted file mode 100644
index df7f92d..0000000
--- a/lib/cocoa/src/TError.m
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.
- */
-
-#import "TError.h"
-
-
-NSString *TErrorDomain = @"TErrorDomain";
diff --git a/lib/cocoa/src/TList.swift b/lib/cocoa/src/TList.swift
deleted file mode 100644
index 005bd81..0000000
--- a/lib/cocoa/src/TList.swift
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.
- */
-
-import Foundation
-
-
-
-public struct TList<Element : TSerializable> : MutableCollectionType, Hashable, ArrayLiteralConvertible, TSerializable {
-
- public static var thriftType : TType { return .LIST }
-
- typealias Storage = Array<Element>
-
- public typealias Index = Storage.Index
-
- private var storage = Storage()
-
- public var startIndex : Index {
- return storage.startIndex
- }
-
- public var endIndex : Index {
- return storage.endIndex
- }
-
- public subscript (position: Index) -> Element {
- get {
- return storage[position]
- }
- set {
- storage[position] = newValue
- }
- }
-
- public var hashValue : Int {
- let prime = 31
- var result = 1
- for element in storage {
- result = prime * result + element.hashValue
- }
- return result
- }
-
- public init(arrayLiteral elements: Element...) {
- self.storage = Storage(storage)
- }
-
- public init() {
- self.storage = Storage()
- }
-
- public mutating func append(newElement: Element) {
- self.storage.append(newElement)
- }
-
- public mutating func appendContentsOf<C : CollectionType where C.Generator.Element == Element>(newstorage: C) {
- self.storage.appendContentsOf(newstorage)
- }
-
- public mutating func insert(newElement: Element, atIndex index: Int) {
- self.storage.insert(newElement, atIndex: index)
- }
-
- public mutating func insertContentsOf<C : CollectionType where C.Generator.Element == Element>(newElements: C, at index: Int) {
- self.storage.insertContentsOf(newElements, at: index)
- }
-
- public mutating func removeAll(keepCapacity keepCapacity: Bool = true) {
- self.storage.removeAll(keepCapacity: keepCapacity)
- }
-
- public mutating func removeAtIndex(index: Index) {
- self.storage.removeAtIndex(index)
- }
-
- public mutating func removeFirst(n: Int = 0) {
- self.storage.removeFirst(n)
- }
-
- public mutating func removeLast() -> Element {
- return self.storage.removeLast()
- }
-
- public mutating func removeRange(subRange: Range<Index>) {
- self.storage.removeRange(subRange)
- }
-
- public mutating func reserveCapacity(minimumCapacity: Int) {
- self.storage.reserveCapacity(minimumCapacity)
- }
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> TList {
- let (elementType, size) = try proto.readListBegin()
- if elementType != Element.thriftType {
- throw NSError(
- domain: TProtocolErrorDomain,
- code: Int(TProtocolError.InvalidData.rawValue),
- userInfo: [TProtocolErrorExtendedErrorKey: NSNumber(int: TProtocolExtendedError.UnexpectedType.rawValue)])
- }
- var list = TList()
- for _ in 0..<size {
- let element = try Element.readValueFromProtocol(proto)
- list.storage.append(element)
- }
- try proto.readListEnd()
- return list
- }
-
- public static func writeValue(value: TList, toProtocol proto: TProtocol) throws {
- try proto.writeListBeginWithElementType(Element.thriftType, size: value.count)
- for element in value.storage {
- try Element.writeValue(element, toProtocol: proto)
- }
- try proto.writeListEnd()
- }
-}
-
-extension TList : CustomStringConvertible, CustomDebugStringConvertible {
-
- public var description : String {
- return storage.description
- }
-
- public var debugDescription : String {
- return storage.debugDescription
- }
-
-}
-
-public func ==<Element>(lhs: TList<Element>, rhs: TList<Element>) -> Bool {
- return lhs.storage == rhs.storage
-}
diff --git a/lib/cocoa/src/TMap.swift b/lib/cocoa/src/TMap.swift
deleted file mode 100644
index e96e747..0000000
--- a/lib/cocoa/src/TMap.swift
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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.
- */
-
-import Foundation
-
-
-public struct TMap<Key : TSerializable, Value : TSerializable> : CollectionType, DictionaryLiteralConvertible, TSerializable {
-
- public static var thriftType : TType { return .MAP }
-
- typealias Storage = Dictionary<Key, Value>
-
- public typealias Index = Storage.Index
-
- public typealias Element = Storage.Element
-
- private var storage : Storage
-
- public var startIndex : Index {
- return storage.startIndex
- }
-
- public var endIndex: Index {
- return storage.endIndex
- }
-
- public var keys: LazyMapCollection<[Key : Value], Key> {
- return storage.keys
- }
-
- public var values: LazyMapCollection<[Key : Value], Value> {
- return storage.values
- }
-
- public init() {
- storage = Storage()
- }
-
- public init(dictionaryLiteral elements: (Key, Value)...) {
- storage = Storage()
- for (key, value) in elements {
- storage[key] = value
- }
- }
-
- public init(minimumCapacity: Int) {
- storage = Storage(minimumCapacity: minimumCapacity)
- }
-
- public subscript (position: Index) -> Element {
- get {
- return storage[position]
- }
- }
-
- public func indexForKey(key: Key) -> Index? {
- return storage.indexForKey(key)
- }
-
- public subscript (key: Key) -> Value? {
- get {
- return storage[key]
- }
- set {
- storage[key] = newValue
- }
- }
-
- public mutating func updateValue(value: Value, forKey key: Key) -> Value? {
- return updateValue(value, forKey: key)
- }
-
- public mutating func removeAtIndex(index: DictionaryIndex<Key, Value>) -> (Key, Value) {
- return removeAtIndex(index)
- }
-
- public mutating func removeValueForKey(key: Key) -> Value? {
- return storage.removeValueForKey(key)
- }
-
- public mutating func removeAll(keepCapacity keepCapacity: Bool = false) {
- storage.removeAll(keepCapacity: keepCapacity)
- }
-
- public var hashValue : Int {
- let prime = 31
- var result = 1
- for (key, value) in storage {
- result = prime * result + key.hashValue
- result = prime * result + value.hashValue
- }
- return result
- }
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> TMap {
- let (keyType, valueType, size) = try proto.readMapBegin()
- if keyType != Key.thriftType || valueType != Value.thriftType {
- throw NSError(
- domain: TProtocolErrorDomain,
- code: Int(TProtocolError.InvalidData.rawValue),
- userInfo: [TProtocolErrorExtendedErrorKey: NSNumber(int: TProtocolExtendedError.UnexpectedType.rawValue)])
- }
- var map = TMap()
- for _ in 0..<size {
- let key = try Key.readValueFromProtocol(proto)
- let value = try Value.readValueFromProtocol(proto)
- map.storage[key] = value
- }
- try proto.readMapEnd()
- return map
- }
-
- public static func writeValue(value: TMap, toProtocol proto: TProtocol) throws {
- try proto.writeMapBeginWithKeyType(Key.thriftType, valueType: Value.thriftType, size: value.count)
- for (key, value) in value.storage {
- try Key.writeValue(key, toProtocol: proto)
- try Value.writeValue(value, toProtocol: proto)
- }
- try proto.writeMapEnd()
- }
-
-}
-
-
-extension TMap : CustomStringConvertible, CustomDebugStringConvertible {
-
- public var description : String {
- return storage.description
- }
-
- public var debugDescription : String {
- return storage.debugDescription
- }
-
-}
-
-public func ==<Key, Value>(lhs: TMap<Key,Value>, rhs: TMap<Key, Value>) -> Bool {
- if lhs.count != rhs.count {
- return false
- }
- return lhs.storage == rhs.storage
-}
diff --git a/lib/cocoa/src/TProcessor.h b/lib/cocoa/src/TProcessor.h
deleted file mode 100644
index 20c72e2..0000000
--- a/lib/cocoa/src/TProcessor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TProtocol.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@protocol TProcessor <NSObject>
-
--(BOOL) processOnInputProtocol:(id <TProtocol>)inProtocol
- outputProtocol:(id <TProtocol>)outProtocol
- error:(NSError **)error;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/TProcessorFactory.h b/lib/cocoa/src/TProcessorFactory.h
deleted file mode 100644
index 85020a5..0000000
--- a/lib/cocoa/src/TProcessorFactory.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TProcessor.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@protocol TProcessorFactory <NSObject>
-
--(id<TProcessor>) processorForTransport:(id<TTransport>)transport;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/TProtocol.swift b/lib/cocoa/src/TProtocol.swift
deleted file mode 100644
index 1775849..0000000
--- a/lib/cocoa/src/TProtocol.swift
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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.
- */
-
-import Foundation
-
-
-public extension TProtocol {
-
- public func readMessageBegin() throws -> (String, TMessageType, Int) {
-
- var name : NSString?
- var type : Int32 = -1
- var sequenceID : Int32 = -1
-
- try readMessageBeginReturningName(&name, type: &type, sequenceID: &sequenceID)
-
- return (name as String!, TMessageType(rawValue: type)!, Int(sequenceID))
- }
-
- public func writeMessageBeginWithName(name: String, type: TMessageType, sequenceID: Int) throws {
- try writeMessageBeginWithName(name, type: type.rawValue, sequenceID: Int32(sequenceID))
- }
-
- public func readStructBegin() throws -> (String?) {
-
- var name : NSString? = nil
-
- try readStructBeginReturningName(&name)
-
- return (name as String?)
- }
-
- public func readFieldBegin() throws -> (String?, TType, Int) {
-
- var name : NSString? = nil
- var type : Int32 = -1
- var fieldID : Int32 = -1
-
- try readFieldBeginReturningName(&name, type: &type, fieldID: &fieldID)
-
- return (name as String?, TType(rawValue: type)!, Int(fieldID))
- }
-
- public func writeFieldBeginWithName(name: String, type: TType, fieldID: Int) throws {
- try writeFieldBeginWithName(name, type: type.rawValue, fieldID: Int32(fieldID))
- }
-
- public func readMapBegin() throws -> (TType, TType, Int32) {
-
- var keyType : Int32 = -1
- var valueType : Int32 = -1
- var size : Int32 = 0
-
- try readMapBeginReturningKeyType(&keyType, valueType: &valueType, size: &size)
-
- return (TType(rawValue: keyType)!, TType(rawValue: valueType)!, size)
- }
-
- public func writeMapBeginWithKeyType(keyType: TType, valueType: TType, size: Int) throws {
- try writeMapBeginWithKeyType(keyType.rawValue, valueType: valueType.rawValue, size: Int32(size))
- }
-
- public func readSetBegin() throws -> (TType, Int32) {
-
- var elementType : Int32 = -1
- var size : Int32 = 0
-
- try readSetBeginReturningElementType(&elementType, size: &size)
-
- return (TType(rawValue: elementType)!, size)
- }
-
- public func writeSetBeginWithElementType(elementType: TType, size: Int) throws {
- try writeSetBeginWithElementType(elementType.rawValue, size: Int32(size))
- }
-
- public func readListBegin() throws -> (TType, Int32) {
-
- var elementType : Int32 = -1
- var size : Int32 = 0
-
- try readListBeginReturningElementType(&elementType, size: &size)
-
- return (TType(rawValue: elementType)!, size)
- }
-
- public func writeListBeginWithElementType(elementType: TType, size: Int) throws {
- try writeListBeginWithElementType(elementType.rawValue, size: Int32(size))
- }
-
- public func writeFieldValue<T: TSerializable>(value: T, name: String, type: TType, id: Int32) throws {
- try writeFieldBeginWithName(name, type: type.rawValue, fieldID: id)
- try writeValue(value)
- try writeFieldEnd()
- }
-
- public func readValue<T: TSerializable>() throws -> T {
- return try T.readValueFromProtocol(self)
- }
-
- public func writeValue<T: TSerializable>(value: T) throws {
- try T.writeValue(value, toProtocol: self)
- }
-
- public func readResultMessageBegin() throws {
-
- let (_, type, _) = try readMessageBegin();
-
- if type == .EXCEPTION {
- let x = try readException()
- throw x
- }
-
- return
- }
-
- public func validateValue(value: Any?, named name: String) throws {
-
- if value == nil {
- throw NSError(
- domain: TProtocolErrorDomain,
- code: Int(TProtocolError.Unknown.rawValue),
- userInfo: [TProtocolErrorFieldNameKey: name])
- }
-
- }
-
- public func readException() throws -> ErrorType {
-
- var reason : String?
- var type = TApplicationError.Unknown
-
- try readStructBegin()
-
- fields: while (true) {
-
- let (_, fieldType, fieldID) = try readFieldBegin()
-
- switch (fieldID, fieldType) {
- case (_, .STOP):
- break fields
-
- case (1, .STRING):
- reason = try readValue() as String
-
- case (2, .I32):
- let typeVal = try readValue() as Int32
- if let tmp = TApplicationError(rawValue: typeVal) {
- type = tmp
- }
-
- case let (_, unknownType):
- try skipType(unknownType)
- }
-
- try readFieldEnd()
- }
-
- try readStructEnd()
-
- return NSError(type:type, reason:reason ?? "")
- }
-
- public func writeExceptionForMessageName(name: String, sequenceID: Int, ex: NSError) throws {
- try writeMessageBeginWithName(name, type: .EXCEPTION, sequenceID: sequenceID)
- try ex.write(self)
- try writeMessageEnd()
- }
-
- public func skipType(type: TType) throws {
- try TProtocolUtil.skipType(type.rawValue, onProtocol: self)
- }
-
-}
diff --git a/lib/cocoa/src/TSerializable.swift b/lib/cocoa/src/TSerializable.swift
deleted file mode 100644
index 3fdfd41..0000000
--- a/lib/cocoa/src/TSerializable.swift
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.
- */
-
-import Foundation
-
-
-public protocol TSerializable : Hashable {
-
- static var thriftType : TType { get }
-
- init()
-
- static func readValueFromProtocol(proto: TProtocol) throws -> Self
-
- static func writeValue(value: Self, toProtocol proto: TProtocol) throws
-
-}
-
-
-
-infix operator ?== {}
-
-public func ?==<T: TSerializable>(lhs: T?, rhs: T?) -> Bool {
- if let l = lhs, r = rhs {
- return l == r
- }
- return lhs == rhs
-}
-
-public func ?==<T: TSerializable>(lhs: T, rhs: T) -> Bool {
- return lhs == rhs
-}
-
-
-
-extension Bool : TSerializable {
-
- public static let thriftType = TType.BOOL
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> Bool {
- var value : ObjCBool = false
- try proto.readBool(&value)
- return value.boolValue
- }
-
- public static func writeValue(value: Bool, toProtocol proto: TProtocol) throws {
- try proto.writeBool(value)
- }
-
-}
-
-extension Int8 : TSerializable {
-
- public static let thriftType = TType.BYTE
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> Int8 {
- var value = UInt8()
- try proto.readByte(&value)
- return Int8(value)
- }
-
- public static func writeValue(value: Int8, toProtocol proto: TProtocol) throws {
- try proto.writeByte(UInt8(value))
- }
-
-}
-
-extension Int16 : TSerializable {
-
- public static let thriftType = TType.I16
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> Int16 {
- var value = Int16()
- try proto.readI16(&value)
- return value
- }
-
- public static func writeValue(value: Int16, toProtocol proto: TProtocol) throws {
- try proto.writeI16(value)
- }
-
-}
-
-extension Int : TSerializable {
-
- public static let thriftType = TType.I32
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> Int {
- var value = Int32()
- try proto.readI32(&value)
- return Int(value)
- }
-
- public static func writeValue(value: Int, toProtocol proto: TProtocol) throws {
- try proto.writeI32(Int32(value))
- }
-
-}
-
-extension Int32 : TSerializable {
-
- public static let thriftType = TType.I32
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> Int32 {
- var value = Int32()
- try proto.readI32(&value)
- return value
- }
-
- public static func writeValue(value: Int32, toProtocol proto: TProtocol) throws {
- try proto.writeI32(value)
- }
-
-}
-
-extension Int64 : TSerializable {
-
- public static let thriftType = TType.I64
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> Int64 {
- var value = Int64()
- try proto.readI64(&value)
- return value
- }
-
- public static func writeValue(value: Int64, toProtocol proto: TProtocol) throws {
- try proto.writeI64(value)
- }
-
-}
-
-extension Double : TSerializable {
-
- public static let thriftType = TType.DOUBLE
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> Double {
- var value = Double()
- try proto.readDouble(&value)
- return value
- }
-
- public static func writeValue(value: Double, toProtocol proto: TProtocol) throws {
- try proto.writeDouble(value)
- }
-
-}
-
-extension String : TSerializable {
-
- public static let thriftType = TType.STRING
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> String {
- var value : NSString?
- try proto.readString(&value)
- return value as! String
- }
-
- public static func writeValue(value: String, toProtocol proto: TProtocol) throws {
- try proto.writeString(value)
- }
-
-}
diff --git a/lib/cocoa/src/TSet.swift b/lib/cocoa/src/TSet.swift
deleted file mode 100644
index 85833e5..0000000
--- a/lib/cocoa/src/TSet.swift
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * 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.
- */
-
-import Foundation
-
-
-public struct TSet<Element : TSerializable> : CollectionType, ArrayLiteralConvertible, TSerializable {
-
- public static var thriftType : TType { return .SET }
-
- public typealias Index = Storage.Index
-
- typealias Storage = Set<Element>
-
- private var storage : Storage
-
- public init() {
- storage = Storage()
- }
-
- public init(arrayLiteral elements: Element...) {
- storage = Storage(elements)
- }
-
- public init<S : SequenceType where S.Generator.Element == Element>(_ sequence: S) {
- storage = Storage(sequence)
- }
-
- public var startIndex : Index { return storage.startIndex }
-
- public var endIndex : Index { return storage.endIndex }
-
- public mutating func insert(member: Element) {
- return storage.insert(member)
- }
-
- public mutating func remove(element: Element) -> Element? {
- return storage.remove(element)
- }
-
- public mutating func removeAll(keepCapacity keepCapacity: Bool = false) {
- return storage.removeAll(keepCapacity: keepCapacity)
- }
-
- public mutating func removeAtIndex(index: SetIndex<Element>) -> Element {
- return storage.removeAtIndex(index)
- }
-
- public subscript (position: SetIndex<Element>) -> Element {
- return storage[position]
- }
-
- public func union(other: TSet) -> TSet {
- return TSet(storage.union(other))
- }
-
- public func intersect(other: TSet) -> TSet {
- return TSet(storage.intersect(other))
- }
-
- public func exclusiveOr(other: TSet) -> TSet {
- return TSet(storage.exclusiveOr(other))
- }
-
- public func subtract(other: TSet) -> TSet {
- return TSet(storage.subtract(other))
- }
-
- public mutating func intersectInPlace(other: TSet) {
- storage.intersectInPlace(other)
- }
-
- public mutating func exclusiveOrInPlace(other: TSet) {
- storage.exclusiveOrInPlace(other)
- }
-
- public mutating func subtractInPlace(other: TSet) {
- storage.subtractInPlace(other)
- }
-
- public func isSubsetOf(other: TSet) -> Bool {
- return storage.isSubsetOf(other)
- }
-
- public func isDisjointWith(other: TSet) -> Bool {
- return storage.isDisjointWith(other)
- }
-
- public func isSupersetOf(other: TSet) -> Bool {
- return storage.isSupersetOf(other)
- }
-
- public var isEmpty: Bool { return storage.isEmpty }
-
- public var hashValue : Int {
- let prime = 31
- var result = 1
- for element in storage {
- result = prime * result + element.hashValue
- }
- return result
- }
-
- public static func readValueFromProtocol(proto: TProtocol) throws -> TSet {
- let (elementType, size) = try proto.readSetBegin()
- if elementType != Element.thriftType {
- throw NSError(
- domain: TProtocolErrorDomain,
- code: Int(TProtocolError.InvalidData.rawValue),
- userInfo: [TProtocolErrorExtendedErrorKey: NSNumber(int: elementType.rawValue)])
- }
- var set = TSet()
- for _ in 0..<size {
- let element = try Element.readValueFromProtocol(proto)
- set.storage.insert(element)
- }
- try proto.readSetEnd()
- return set
- }
-
- public static func writeValue(value: TSet, toProtocol proto: TProtocol) throws {
- try proto.writeSetBeginWithElementType(Element.thriftType, size: value.count)
- for element in value.storage {
- try Element.writeValue(element, toProtocol: proto)
- }
- try proto.writeSetEnd()
- }
-
-}
-
-extension TSet : CustomStringConvertible, CustomDebugStringConvertible {
-
- public var description : String {
- return storage.description
- }
-
- public var debugDescription : String {
- return storage.debugDescription
- }
-
-}
-
-public func ==<Element>(lhs: TSet<Element>, rhs: TSet<Element>) -> Bool {
- return lhs.storage == rhs.storage
-}
diff --git a/lib/cocoa/src/TSharedProcessorFactory.h b/lib/cocoa/src/TSharedProcessorFactory.h
deleted file mode 100644
index c75fad1..0000000
--- a/lib/cocoa/src/TSharedProcessorFactory.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TProcessorFactory.h"
-
-
-@interface TSharedProcessorFactory : NSObject <TProcessorFactory>
-
--(id) initWithSharedProcessor:(id<TProcessor>)sharedProcessor;
-
-@end
diff --git a/lib/cocoa/src/TSharedProcessorFactory.m b/lib/cocoa/src/TSharedProcessorFactory.m
deleted file mode 100644
index 3d55f47..0000000
--- a/lib/cocoa/src/TSharedProcessorFactory.m
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.
- */
-
-
-#import "TSharedProcessorFactory.h"
-
-
-@interface TSharedProcessorFactory ()
-
-@property(strong, nonatomic) id<TProcessor> sharedProcessor;
-
-@end
-
-
-@implementation TSharedProcessorFactory
-
-
--(id) initWithSharedProcessor:(id<TProcessor>)sharedProcessor
-{
- self = [super init];
- if (self) {
- _sharedProcessor = sharedProcessor;
- }
-
- return self;
-}
-
--(id<TProcessor>) processorForTransport:(id<TTransport>)transport
-{
- return _sharedProcessor;
-}
-
-@end
diff --git a/lib/cocoa/src/TStruct.swift b/lib/cocoa/src/TStruct.swift
deleted file mode 100644
index cea72e7..0000000
--- a/lib/cocoa/src/TStruct.swift
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-
-import Foundation
-
-
-public protocol TStruct : TSerializable {
-}
-
-
-public extension TStruct {
-
- public static var thriftType : TType { return TType.STRUCT }
-
-}
diff --git a/lib/cocoa/src/Thrift.h b/lib/cocoa/src/Thrift.h
deleted file mode 100644
index 18488f9..0000000
--- a/lib/cocoa/src/Thrift.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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.
- */
-
-#define ThriftVersion @"0.12.1"
diff --git a/lib/cocoa/src/protocol/TBase.h b/lib/cocoa/src/protocol/TBase.h
deleted file mode 100644
index 9935d50..0000000
--- a/lib/cocoa/src/protocol/TBase.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-
-#import "TProtocol.h"
-
-@protocol TBase <NSObject>
-
-/**
- * De-serialize object from the given input protocol
- *
- * @param inProtocol protocol used for reading
- */
--(BOOL) read:(id <TProtocol>)inProtocol error:(NSError **)error;
-
-/**
- * Serialize object to the given protocol
- *
- * @param outProtocol output protocol used for writing
- */
--(BOOL) write:(id <TProtocol>)outProtocol error:(NSError **)error;
-
-
-/**
- * Validate required fields
- */
--(BOOL) validate:(NSError *__autoreleasing *)__thriftError;
-
-@end
diff --git a/lib/cocoa/src/protocol/TBinaryProtocol.h b/lib/cocoa/src/protocol/TBinaryProtocol.h
deleted file mode 100644
index bb90fad..0000000
--- a/lib/cocoa/src/protocol/TBinaryProtocol.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.
- */
-
-#import "TProtocol.h"
-#import "TTransport.h"
-#import "TProtocolFactory.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@interface TBinaryProtocol : NSObject <TProtocol>
-
-@property (assign, nonatomic) UInt32 messageSizeLimit;
-
--(id) initWithTransport:(id <TTransport>)transport;
-
--(id) initWithTransport:(id <TTransport>)transport
- strictRead:(BOOL)strictRead
- strictWrite:(BOOL)strictWrite;
-
-@end;
-
-
-@interface TBinaryProtocolFactory : NSObject <TProtocolFactory>
-
-+(TBinaryProtocolFactory *) sharedFactory;
-
--(TBinaryProtocol *) newProtocolOnTransport:(id <TTransport>)transport;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
\ No newline at end of file
diff --git a/lib/cocoa/src/protocol/TBinaryProtocol.m b/lib/cocoa/src/protocol/TBinaryProtocol.m
deleted file mode 100644
index 1f9e57a..0000000
--- a/lib/cocoa/src/protocol/TBinaryProtocol.m
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * 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.
- */
-
-#import "TBinaryProtocol.h"
-#import "TProtocolError.h"
-
-
-static SInt32 VERSION_1 = 0x80010000;
-static SInt32 VERSION_MASK = 0xffff0000;
-
-
-static TBinaryProtocolFactory *gSharedFactory = nil;
-
-
-@implementation TBinaryProtocolFactory
-
-+(TBinaryProtocolFactory *) sharedFactory
-{
- if (gSharedFactory == nil) {
- gSharedFactory = [[TBinaryProtocolFactory alloc] init];
- }
-
- return gSharedFactory;
-}
-
--(NSString *) protocolName
-{
- return @"binary";
-}
-
--(TBinaryProtocol *) newProtocolOnTransport:(id <TTransport>)transport
-{
- return [[TBinaryProtocol alloc] initWithTransport:transport];
-}
-
-@end
-
-
-@interface TBinaryProtocol ()
-
-@property(strong, nonatomic) id <TTransport> transport;
-
-@property(assign, nonatomic) BOOL strictRead;
-@property(assign, nonatomic) BOOL strictWrite;
-
-@property(strong, nonatomic) NSString *currentMessageName;
-@property(strong, nonatomic) NSString *currentFieldName;
-
-@end
-
-
-@implementation TBinaryProtocol
-
--(id) initWithTransport:(id <TTransport>)aTransport
-{
- return [self initWithTransport:aTransport strictRead:NO strictWrite:YES];
-}
-
--(id) initWithTransport:(id <TTransport>)transport
- strictRead:(BOOL)strictRead
- strictWrite:(BOOL)strictWrite
-{
- self = [super init];
- if (self) {
- _transport = transport;
- _strictRead = strictRead;
- _strictWrite = strictWrite;
- }
- return self;
-}
-
--(id <TTransport>) transport
-{
- return _transport;
-}
-
--(NSString *) readStringBody:(int)size error:(NSError **)error
-{
- NSMutableData *data = [NSMutableData dataWithLength:size];
- if (!data) {
- PROTOCOL_ERROR(nil, Unknown, @"Unable to allocate %d bytes", size);
- }
-
- if (![_transport readAll:data.mutableBytes offset:0 length:size error:error]) {
- PROTOCOL_TRANSPORT_ERROR(nil, error, @"Transport read failed");
- }
-
- return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
-}
-
-
--(BOOL) readMessageBeginReturningName:(NSString **)name
- type:(SInt32 *)type
- sequenceID:(SInt32 *)sequenceID
- error:(NSError *__autoreleasing *)error
-{
- SInt32 size;
- if (![self readI32:&size error:error]) {
- return NO;
- }
- ;
-
- if (size < 0) {
- int version = size & VERSION_MASK;
- if (version != VERSION_1) {
- PROTOCOL_ERROR(NO, BadVersion, @"Bad message version");
- }
- if (type != NULL) {
- *type = size & 0x00FF;
- }
- NSString *messageName;
- if (![self readString:&messageName error:error]) {
- return NO;
- }
- if (name != nil) {
- *name = messageName;
- }
- }
- else {
-
- if (_strictRead) {
- PROTOCOL_ERROR(NO, InvalidData, @"Missing message version, old client?");
- }
-
- if (_messageSizeLimit > 0 && size > _messageSizeLimit) {
- PROTOCOL_ERROR(NO, SizeLimit, @"Message exceeeds size limit of %d", (int)size);
- }
-
- NSString *messageName = [self readStringBody:size error:error];
- if (!messageName) {
- return NO;
- }
-
- if (name != NULL) {
- *name = messageName;
- }
-
- UInt8 messageType;
- if (![self readByte:&messageType error:error]) {
- return NO;
- }
-
- if (type != NULL) {
- *type = messageType;
- }
- }
-
- SInt32 seqID;
- if (![self readI32:&seqID error:error]) {
- return NO;
- }
- if (sequenceID != NULL) {
- *sequenceID = seqID;
- }
-
- return YES;
-}
-
-
--(BOOL) readMessageEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
--(BOOL) readStructBeginReturningName:(NSString *__autoreleasing *)name error:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
--(BOOL) readStructEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
--(BOOL) readFieldBeginReturningName:(NSString *__autoreleasing *)name
- type:(SInt32 *)fieldType
- fieldID:(SInt32 *)fieldID
- error:(NSError *__autoreleasing *)error
-{
- if (name != nil) {
- *name = nil;
- }
-
- UInt8 ft;
- if (![self readByte:&ft error:error]) {
- return NO;
- }
- if (fieldType != NULL) {
- *fieldType = ft;
- }
- if (ft != TTypeSTOP) {
- SInt16 fid;
- if (![self readI16:&fid error:error]) {
- return NO;
- }
- if (fieldID != NULL) {
- *fieldID = fid;
- }
- }
- return YES;
-}
-
-
--(BOOL) readFieldEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
--(BOOL) readString:(NSString *__autoreleasing *)value error:(NSError *__autoreleasing *)error
-{
- SInt32 size;
- if (![self readI32:&size error:error]) {
- return NO;
- }
-
- NSString *string = [self readStringBody:size error:error];
- if (!string) {
- return NO;
- }
-
- *value = string;
-
- return YES;
-}
-
-
--(BOOL) readBool:(BOOL *)value error:(NSError *__autoreleasing *)error
-{
- UInt8 byte;
- if (![self readByte:&byte error:error]) {
- return NO;
- }
-
- *value = byte == 1;
-
- return YES;
-}
-
-
--(BOOL) readByte:(UInt8 *)value error:(NSError *__autoreleasing *)error
-{
- UInt8 buff[1];
- if (![_transport readAll:buff offset:0 length:1 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
- }
-
- *value = buff[0];
-
- return YES;
-}
-
-
--(BOOL) readI16:(SInt16 *)value error:(NSError *__autoreleasing *)error
-{
- UInt8 buff[2];
- if (![_transport readAll:buff offset:0 length:2 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
- }
-
- *value =
- ((SInt16)(buff[0] & 0xff) << 8) |
- ((SInt16)(buff[1] & 0xff));
-
- return YES;
-}
-
-
--(BOOL) readI32:(SInt32 *)value error:(NSError *__autoreleasing *)error
-{
- UInt8 i32rd[4];
- if (![_transport readAll:i32rd offset:0 length:4 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
- }
-
- *value =
- ((i32rd[0] & 0xff) << 24) |
- ((i32rd[1] & 0xff) << 16) |
- ((i32rd[2] & 0xff) << 8) |
- ((i32rd[3] & 0xff));
-
- return YES;
-}
-
-
--(BOOL) readI64:(SInt64 *)value error:(NSError *__autoreleasing *)error
-{
- UInt8 buff[8];
- if (![_transport readAll:buff offset:0 length:8 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
- }
-
- *value =
- ((SInt64)(buff[0] & 0xff) << 56) |
- ((SInt64)(buff[1] & 0xff) << 48) |
- ((SInt64)(buff[2] & 0xff) << 40) |
- ((SInt64)(buff[3] & 0xff) << 32) |
- ((SInt64)(buff[4] & 0xff) << 24) |
- ((SInt64)(buff[5] & 0xff) << 16) |
- ((SInt64)(buff[6] & 0xff) << 8) |
- ((SInt64)(buff[7] & 0xff));
-
- return YES;
-}
-
-
--(BOOL) readDouble:(double *)value error:(NSError *__autoreleasing *)error
-{
- // FIXME - will this get us into trouble on PowerPC?
- return [self readI64:(SInt64 *)value error:error];
-}
-
-
--(BOOL) readBinary:(NSData *__autoreleasing *)value error:(NSError *__autoreleasing *)error
-{
- SInt32 size;
- if (![self readI32:&size error:error]) {
- return NO;
- }
-
- NSMutableData *data = [NSMutableData dataWithLength:size];
- if (!data) {
- PROTOCOL_ERROR(NO, Unknown, @"Unable to allocate %d bytes", (int)size);
- }
-
- if (![_transport readAll:data.mutableBytes offset:0 length:size error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
- }
-
- *value = data;
-
- return YES;
-}
-
-
--(BOOL) readMapBeginReturningKeyType:(SInt32 *)keyType
- valueType:(SInt32 *)valueType
- size:(SInt32 *)size
- error:(NSError *__autoreleasing *)error
-{
- UInt8 kt;
- if (![self readByte:&kt error:error]) {
- return NO;
- }
-
- UInt8 vt;
- if (![self readByte:&vt error:error]) {
- return NO;
- }
-
- SInt32 s;
- if (![self readI32:&s error:error]) {
- return NO;
- }
-
- if (keyType != NULL) {
- *keyType = kt;
- }
-
- if (valueType != NULL) {
- *valueType = vt;
- }
-
- if (size != NULL) {
- *size = s;
- }
-
- return YES;
-}
-
-
--(BOOL) readMapEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
--(BOOL) readSetBeginReturningElementType:(SInt32 *)elementType
- size:(SInt32 *)size
- error:(NSError *__autoreleasing *)error
-{
- UInt8 et;
- if (![self readByte:&et error:error]) {
- return NO;
- }
-
- SInt32 s;
- if (![self readI32:&s error:error]) {
- return NO;
- }
-
- if (elementType != NULL) {
- *elementType = et;
- }
-
- if (size != NULL) {
- *size = s;
- }
-
- return YES;
-}
-
-
--(BOOL) readSetEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
--(BOOL) readListBeginReturningElementType:(SInt32 *)elementType
- size:(SInt32 *)size
- error:(NSError *__autoreleasing *)error
-{
- UInt8 et;
- if (![self readByte:&et error:error]) {
- return NO;
- }
-
- SInt32 s;
- if (![self readI32:&s error:error]) {
- return NO;
- }
-
- if (elementType != NULL) {
- *elementType = et;
- }
-
- if (size != NULL) {
- *size = s;
- }
-
- return YES;
-}
-
-
--(BOOL) readListEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
-
--(BOOL) writeMessageBeginWithName:(NSString *)name
- type:(SInt32)messageType
- sequenceID:(SInt32)sequenceID
- error:(NSError *__autoreleasing *)error
-{
- if (_strictWrite) {
-
- int version = VERSION_1 | messageType;
-
- if (![self writeI32:version error:error]) {
- return NO;
- }
-
- if (![self writeString:name error:error]) {
- return NO;
- }
-
- if (![self writeI32:sequenceID error:error]) {
- return NO;
- }
- }
- else {
-
- if (![self writeString:name error:error]) {
- return NO;
- }
-
- if (![self writeByte:messageType error:error]) {
- return NO;
- }
-
- if (![self writeI32:sequenceID error:error]) {
- return NO;
- }
- }
-
- _currentMessageName = name;
-
- return YES;
-}
-
-
--(BOOL) writeMessageEnd:(NSError *__autoreleasing *)error
-{
- _currentMessageName = nil;
- return YES;
-}
-
-
--(BOOL) writeStructBeginWithName:(NSString *)name
- error:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
--(BOOL) writeStructEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
--(BOOL) writeFieldBeginWithName:(NSString *)name
- type:(SInt32)fieldType
- fieldID:(SInt32)fieldID
- error:(NSError *__autoreleasing *)error
-{
- if (![self writeByte:fieldType error:error]) {
- return NO;
- }
-
- if (![self writeI16:fieldID error:error]) {
- return NO;
- }
-
- return YES;
-}
-
-
--(BOOL) writeBool:(BOOL)value error:(NSError *__autoreleasing *)error
-{
- return [self writeByte:(value ? 1 : 0) error:error];
-}
-
-
--(BOOL) writeByte:(UInt8)value error:(NSError *__autoreleasing *)error
-{
- if (![_transport write:&value offset:0 length:1 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
- }
- return YES;
-}
-
-
--(BOOL) writeI16:(short)value error:(NSError *__autoreleasing *)error
-{
- UInt8 buff[2];
- buff[0] = 0xff & (value >> 8);
- buff[1] = 0xff & value;
-
- if (![_transport write:buff offset:0 length:2 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
- }
-
- return YES;
-}
-
-
--(BOOL) writeI32:(SInt32)value error:(NSError *__autoreleasing *)error
-{
- UInt8 buff[4];
- buff[0] = 0xFF & (value >> 24);
- buff[1] = 0xFF & (value >> 16);
- buff[2] = 0xFF & (value >> 8);
- buff[3] = 0xFF & value;
-
- if (![_transport write:buff offset:0 length:4 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
- }
-
- return YES;
-}
-
-
--(BOOL) writeI64:(SInt64)value error:(NSError *__autoreleasing *)error
-{
- UInt8 buff[8];
- buff[0] = 0xFF & (value >> 56);
- buff[1] = 0xFF & (value >> 48);
- buff[2] = 0xFF & (value >> 40);
- buff[3] = 0xFF & (value >> 32);
- buff[4] = 0xFF & (value >> 24);
- buff[5] = 0xFF & (value >> 16);
- buff[6] = 0xFF & (value >> 8);
- buff[7] = 0xFF & value;
-
- if (![_transport write:buff offset:0 length:8 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
- }
-
- return YES;
-}
-
-
--(BOOL) writeDouble:(double)value error:(NSError *__autoreleasing *)error
-{
- // FIXME - will this get us in trouble on PowerPC?
- if (![self writeI64:*(SInt64 *)&value error:error]) {
- return NO;
- }
-
- return YES;
-}
-
-
--(BOOL) writeString:(NSString *)value error:(NSError *__autoreleasing *)error
-{
- if (value != nil) {
-
- const char *utf8Bytes = [value UTF8String];
-
- SInt32 length = (SInt32)strlen(utf8Bytes);
- if (![self writeI32:length error:error]) {
- return NO;
- }
-
- if (![_transport write:(UInt8 *)utf8Bytes offset:0 length:(int)length error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
- }
-
- }
- else {
-
- // instead of crashing when we get null, let's write out a zero
- // length string
- if (![self writeI32:0 error:error]) {
- return NO;
- }
-
- }
-
- return YES;
-}
-
-
--(BOOL) writeBinary:(NSData *)data error:(NSError *__autoreleasing *)error
-{
- if (![self writeI32:(SInt32)data.length error:error]) {
- return NO;
- }
-
- if (![_transport write:data.bytes offset:0 length:(UInt32)data.length error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
- }
-
- return YES;
-}
-
-
--(BOOL) writeFieldStop:(NSError *__autoreleasing *)error
-{
- if (![self writeByte:TTypeSTOP error:error]) {
- return NO;
- }
-
- return YES;
-}
-
-
--(BOOL) writeFieldEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
--(BOOL) writeMapBeginWithKeyType:(SInt32)keyType
- valueType:(SInt32)valueType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error
-{
- if (![self writeByte:keyType error:error]) {
- return NO;
- }
- if (![self writeByte:valueType error:error]) {
- return NO;
- }
- if (![self writeI32:(int)size error:error]) {
- return NO;
- }
- return YES;
-}
-
-
--(BOOL) writeMapEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
--(BOOL) writeSetBeginWithElementType:(SInt32)elementType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error
-{
- if (![self writeByte:elementType error:error]) {
- return NO;
- }
- if (![self writeI32:size error:error]) {
- return NO;
- }
- return YES;
-}
-
-
--(BOOL) writeSetEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-
--(BOOL) writeListBeginWithElementType:(SInt32)elementType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error
-{
- if (![self writeByte:elementType error:error]) {
- return NO;
- }
- if (![self writeI32:size error:error]) {
- return NO;
- }
- return YES;
-}
-
-
--(BOOL) writeListEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-@end
diff --git a/lib/cocoa/src/protocol/TCompactProtocol.h b/lib/cocoa/src/protocol/TCompactProtocol.h
deleted file mode 100644
index 3f6accc..0000000
--- a/lib/cocoa/src/protocol/TCompactProtocol.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.
- */
-
-#import "TProtocol.h"
-#import "TTransport.h"
-#import "TProtocolFactory.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@interface TCompactProtocol : NSObject <TProtocol>
-
--(id) initWithTransport:(id <TTransport>)transport;
-
-@end
-
-@interface TCompactProtocolFactory : NSObject <TProtocolFactory>
-
-+(TCompactProtocolFactory *) sharedFactory;
-
--(TCompactProtocol *) newProtocolOnTransport:(id <TTransport>)transport;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
\ No newline at end of file
diff --git a/lib/cocoa/src/protocol/TCompactProtocol.m b/lib/cocoa/src/protocol/TCompactProtocol.m
deleted file mode 100644
index 9b0ebb2..0000000
--- a/lib/cocoa/src/protocol/TCompactProtocol.m
+++ /dev/null
@@ -1,983 +0,0 @@
-/*
- * 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.
- */
-
-#import "TCompactProtocol.h"
-#import "TProtocolError.h"
-
-static const UInt8 COMPACT_PROTOCOL_ID = 0x82;
-static const UInt8 COMPACT_VERSION = 1;
-static const UInt8 COMPACT_VERSION_MASK = 0x1F; // 0001 1111
-static const UInt8 COMPACT_TYPE_MASK = 0xE0; // 1110 0000
-static const UInt8 COMPACT_TYPE_BITS = 0x07; // 0000 0111
-static const int COMPACT_TYPE_SHIFT_AMOUNT = 5;
-
-enum {
- TCType_STOP = 0x00,
- TCType_BOOLEAN_TRUE = 0x01,
- TCType_BOOLEAN_FALSE = 0x02,
- TCType_BYTE = 0x03,
- TCType_I16 = 0x04,
- TCType_I32 = 0x05,
- TCType_I64 = 0x06,
- TCType_DOUBLE = 0x07,
- TCType_BINARY = 0x08,
- TCType_LIST = 0x09,
- TCType_SET = 0x0A,
- TCType_MAP = 0x0B,
- TCType_STRUCT = 0x0C,
-};
-
-@implementation TCompactProtocolFactory
-
-+(TCompactProtocolFactory *) sharedFactory
-{
- static TCompactProtocolFactory *gSharedFactory = nil;
- if (gSharedFactory == nil) {
- gSharedFactory = [[TCompactProtocolFactory alloc] init];
- }
-
- return gSharedFactory;
-}
-
--(NSString *) protocolName
-{
- return @"compact";
-}
-
--(TCompactProtocol *) newProtocolOnTransport:(id <TTransport>)transport
-{
- return [[TCompactProtocol alloc] initWithTransport:transport];
-}
-
-@end
-
-
-@interface TCompactProtocol ()
-
-@property(strong, nonatomic) id <TTransport> transport;
-
-@property(strong, nonatomic) NSMutableArray *lastField;
-@property(assign, nonatomic) short lastFieldId;
-
-@property(strong, nonatomic) NSString *boolFieldName;
-@property(strong, nonatomic) NSNumber *boolFieldType;
-@property(strong, nonatomic) NSNumber *boolFieldId;
-@property(strong, nonatomic) NSNumber *booleanValue;
-
-@property(strong, nonatomic) NSString *currentMessageName;
-
-@end
-
-
-@implementation TCompactProtocol
-
--(id) init
-{
- self = [super init];
-
- if (self != nil) {
- _lastField = [[NSMutableArray alloc] init];
- }
-
- return self;
-}
-
--(id) initWithTransport:(id <TTransport>)aTransport
-{
- self = [self init];
-
- if (self != nil) {
- _transport = aTransport;
- }
-
- return self;
-}
-
--(id <TTransport>) transport
-{
- return _transport;
-}
-
--(BOOL) writeByteDirect:(UInt8)n error:(NSError *__autoreleasing *)error
-{
- if (![_transport write:(UInt8 *)&n offset:0 length:1 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
- }
- return YES;
-}
-
--(BOOL) writeVarint32:(UInt32)n error:(NSError *__autoreleasing *)error
-{
- UInt8 i32buf[5] = {0};
- UInt32 idx = 0;
-
- while (true) {
- if ((n & ~0x7F) == 0) {
- i32buf[idx++] = (UInt8)n;
- break;
- }
- else {
- i32buf[idx++] = (UInt8)((n & 0x7F) | 0x80);
- n >>= 7;
- }
- }
-
- if (![_transport write:i32buf offset:0 length:idx error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
- }
-
- return YES;
-}
-
--(BOOL) writeMessageBeginWithName:(NSString *)name
- type:(SInt32)messageType
- sequenceID:(SInt32)sequenceID
- error:(NSError *__autoreleasing *)error
-{
- if (![self writeByteDirect:COMPACT_PROTOCOL_ID error:error]) {
- return NO;
- }
- if (![self writeByteDirect:(UInt8)((COMPACT_VERSION & COMPACT_VERSION_MASK) |
- ((((UInt32)messageType) << COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_MASK)) error:error])
- {
- return NO;
- }
- if (![self writeVarint32:(UInt32)sequenceID error:error]) {
- return NO;
- }
- if (![self writeString:name error:error]) {
- return NO;
- }
-
- _currentMessageName = name;
-
- return YES;
-}
-
--(BOOL) writeStructBeginWithName:(NSString *)name error:(NSError *__autoreleasing *)error
-{
- [_lastField addObject:@(_lastFieldId)];
- _lastFieldId = 0;
- return YES;
-}
-
--(BOOL) writeStructEnd:(NSError *__autoreleasing *)error
-{
- _lastFieldId = [_lastField.lastObject shortValue];
- [_lastField removeLastObject];
- return YES;
-}
-
--(BOOL) writeFieldBeginWithName:(NSString *)name
- type:(SInt32)fieldType
- fieldID:(SInt32)fieldID
- error:(NSError *__autoreleasing *)error
-{
- if (fieldType == TTypeBOOL) {
- _boolFieldName = [name copy];
- _boolFieldType = @(fieldType);
- _boolFieldId = @(fieldID);
- return YES;
- }
- else {
- return [self writeFieldBeginInternalWithName:name
- type:fieldType
- fieldID:fieldID
- typeOverride:0xFF
- error:error];
- }
-}
-
--(BOOL) writeFieldBeginInternalWithName:(NSString *)name
- type:(SInt32)fieldType
- fieldID:(SInt32)fieldID
- typeOverride:(UInt8)typeOverride
- error:(NSError *__autoreleasing *)error
-{
- UInt8 typeToWrite = typeOverride == 0xFF ? [self compactTypeForTType:fieldType] : typeOverride;
-
- // check if we can use delta encoding for the field id
- if (fieldID > _lastFieldId && fieldID - _lastFieldId <= 15) {
- // Write them together
- if (![self writeByteDirect:(fieldID - _lastFieldId) << 4 | typeToWrite error:error]) {
- return NO;
- }
- }
- else {
- // Write them separate
- if (![self writeByteDirect:typeToWrite error:error]) {
- return NO;
- }
- if (![self writeI16:fieldID error:error]) {
- return NO;
- }
- }
-
- _lastFieldId = fieldID;
-
- return YES;
-}
-
--(BOOL) writeFieldStop:(NSError *__autoreleasing *)error
-{
- return [self writeByteDirect:TCType_STOP error:error];
-}
-
--(BOOL) writeMapBeginWithKeyType:(SInt32)keyType
- valueType:(SInt32)valueType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error
-{
- if (size == 0) {
- if (![self writeByteDirect:0 error:error]) {
- return NO;
- }
- }
- else {
- if (![self writeVarint32:(UInt32)size error:error]) {
- return NO;
- }
- if (![self writeByteDirect:[self compactTypeForTType:keyType] << 4 | [self compactTypeForTType:valueType] error:error]) {
- return NO;
- }
- }
- return YES;
-}
-
--(BOOL) writeListBeginWithElementType:(SInt32)elementType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error
-{
- return [self writeCollectionBeginWithElementType:elementType size:size error:error];
-}
-
--(BOOL) writeSetBeginWithElementType:(SInt32)elementType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error
-{
- return [self writeCollectionBeginWithElementType:elementType size:size error:error];
-}
-
--(BOOL) writeBool:(BOOL)b error:(NSError *__autoreleasing *)error
-{
- BOOL result;
- if (_boolFieldId != nil && _boolFieldName != nil && _boolFieldType != nil) {
- // we haven't written the field header yet
- result = [self writeFieldBeginInternalWithName:_boolFieldName
- type:_boolFieldType.intValue
- fieldID:_boolFieldId.intValue
- typeOverride:b ? TCType_BOOLEAN_TRUE : TCType_BOOLEAN_FALSE
- error:error];
- _boolFieldId = nil;
- _boolFieldName = nil;
- _boolFieldType = nil;
- }
- else {
- // we're not part of a field, so just Write the value.
- result = [self writeByteDirect:b ? TCType_BOOLEAN_TRUE : TCType_BOOLEAN_FALSE error:error];
- }
- return result;
-}
-
--(BOOL) writeByte:(UInt8)value error:(NSError *__autoreleasing *)error
-{
- return [self writeByteDirect:value error:error];
-}
-
--(BOOL) writeI16:(SInt16)value error:(NSError *__autoreleasing *)error
-{
- return [self writeVarint32:[self i32ToZigZag:value] error:error];
-}
-
--(BOOL) writeI32:(SInt32)value error:(NSError *__autoreleasing *)error
-{
- return [self writeVarint32:[self i32ToZigZag:value] error:error];
-}
-
--(BOOL) writeI64:(SInt64)value error:(NSError *__autoreleasing *)error
-{
- return [self writeVarint64:[self i64ToZigZag:value] error:error];
-}
-
--(BOOL) writeDouble:(double)value error:(NSError *__autoreleasing *)error
-{
- // Safe bit-casting double->uint64
-
- UInt64 bits = 0;
- memcpy(&bits, &value, 8);
-
- bits = OSSwapHostToLittleInt64(bits);
-
- if (![_transport write:(UInt8 *)&bits offset:0 length:8 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
- }
-
- return YES;
-}
-
--(BOOL) writeString:(NSString *)value error:(NSError *__autoreleasing *)error
-{
- return [self writeBinary:[value dataUsingEncoding:NSUTF8StringEncoding] error:error];
-}
-
--(BOOL) writeBinary:(NSData *)data error:(NSError *__autoreleasing *)error
-{
- if (![self writeVarint32:(UInt32)data.length error:error]) {
- return NO;
- }
- if (![_transport write:data.bytes offset:0 length:(UInt32)data.length error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
- }
- return YES;
-}
-
--(BOOL) writeMessageEnd:(NSError *__autoreleasing *)error
-{
- _currentMessageName = nil;
- return YES;
-}
-
--(BOOL) writeMapEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
--(BOOL) writeListEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
--(BOOL) writeSetEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
--(BOOL) writeFieldEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
--(BOOL) writeCollectionBeginWithElementType:(SInt32)elementType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error
-{
- UInt8 ctypeElement = [self compactTypeForTType:elementType];
-
- if (size <= 14) {
- if (![self writeByteDirect:size << 4 | ctypeElement error:error]) {
- return NO;
- }
- }
- else {
- if (![self writeByteDirect:0xf0 | ctypeElement error:error]) {
- return NO;
- }
- if (![self writeVarint32:(UInt32)size error:error]) {
- return NO;
- }
- }
- return YES;
-}
-
--(BOOL) writeVarint64:(UInt64)n error:(NSError *__autoreleasing *)error
-{
- UInt8 varint64out[10] = {0};
- int idx = 0;
-
- while (true) {
- if ((n & ~0x7FL) == 0) {
- varint64out[idx++] = (UInt8)n;
- break;
- }
- else {
- varint64out[idx++] = (UInt8)((n & 0x7F) | 0x80);
- n >>= 7;
- }
- }
-
- if (![_transport write:varint64out offset:0 length:idx error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
- }
-
- return YES;
-}
-
--(UInt32) i32ToZigZag:(SInt32)n
-{
- /*
- ZigZag encoding maps signed integers to unsigned integers so that
- numbers with a small absolute value (for instance, -1) have
- a small varint encoded value too. It does this in a way that
- "zig-zags" back and forth through the positive and negative integers,
- so that -1 is encoded as 1, 1 is encoded as 2, -2 is encoded as 3, and so
- on
- */
- return (UInt32)(n << 1) ^ (UInt32)(n >> 31);
-}
-
--(UInt64) i64ToZigZag:(SInt64)n
-{
- return (UInt64)(n << 1) ^ (UInt64)(n >> 63);
-}
-
--(BOOL) readMessageBeginReturningName:(NSString **)pname
- type:(SInt32 *)ptype
- sequenceID:(SInt32 *)psequenceID
- error:(NSError *__autoreleasing *)error
-{
- UInt8 protocolId;
- if (![self readByte:&protocolId error:error]) {
- return NO;
- }
-
- if (protocolId != COMPACT_PROTOCOL_ID) {
- if (error) {
- *error = [NSError errorWithDomain:TProtocolErrorDomain
- code:TProtocolErrorUnknown
- userInfo:@{TProtocolErrorExtendedErrorKey: @(TProtocolExtendedErrorMismatchedProtocol),
- TProtocolErrorExpectedIdKey: @(COMPACT_PROTOCOL_ID)}];
- }
- return NO;
- }
-
- UInt8 versionAndType;
- if (![self readByte:&versionAndType error:error]) {
- return NO;
- }
-
- UInt8 version = versionAndType & COMPACT_VERSION_MASK;
- if (version != COMPACT_VERSION) {
- if (error) {
- *error = [NSError errorWithDomain:TProtocolErrorDomain
- code:TProtocolErrorBadVersion
- userInfo:@{TProtocolErrorExpectedVersionKey: @(COMPACT_VERSION)}];
- }
- return NO;
- }
-
- int type = (versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_BITS;
- UInt32 sequenceID;
- if (![self readVarint32:&sequenceID error:error]) {
- return NO;
- }
- NSString *name;
- if (![self readString:&name error:error]) {
- return NO;
- }
-
- if (ptype != NULL) {
- *ptype = type;
- }
- if (psequenceID != NULL) {
- *psequenceID = sequenceID;
- }
- if (pname != NULL) {
- *pname = name;
- }
- return YES;
-}
-
--(BOOL) readStructBeginReturningName:(NSString **)pname error:(NSError *__autoreleasing *)error
-{
- [_lastField addObject:@(_lastFieldId)];
- _lastFieldId = 0;
-
- if (pname != NULL) {
- *pname = @"";
- }
-
- return YES;
-}
-
--(BOOL) readStructEnd:(NSError *__autoreleasing *)error
-{
- _lastFieldId = [_lastField.lastObject shortValue];
- [_lastField removeLastObject];
- return YES;
-}
-
--(BOOL) readFieldBeginReturningName:(NSString **)pname
- type:(SInt32 *)pfieldType
- fieldID:(SInt32 *)pfieldID
- error:(NSError *__autoreleasing *)error
-{
- UInt8 byte;
- if (![self readByte:&byte error:error]) {
- return NO;
- }
-
- UInt8 type = byte & 0x0f;
-
- // if it's a stop, then we can return immediately, as the struct is over.
- if (type == TCType_STOP) {
- if (pname != NULL) {
- *pname = @"";
- }
- if (pfieldType != NULL) {
- *pfieldType = TTypeSTOP;
- }
- if (pfieldID != NULL) {
- *pfieldID = 0;
- }
- return YES;
- }
-
- short fieldId = 0;
-
- // mask off the 4 MSB of the type header. it could contain a field id delta.
- short modifier = (byte & 0xf0) >> 4;
- if (modifier == 0) {
- // not a delta. look ahead for the zigzag varint field id.
- if (![self readI16:&fieldId error:error]) {
- return NO;
- }
- }
- else {
- // has a delta. add the delta to the last Read field id.
- fieldId = _lastFieldId + modifier;
- }
-
- UInt8 fieldType;
- if (![self ttype:&fieldType forCompactType:type error:error]) {
- return NO;
- }
-
- if (pname != NULL) {
- *pname = @"";
- }
- if (pfieldType != NULL) {
- *pfieldType = fieldType;
- }
- if (pfieldID != NULL) {
- *pfieldID = fieldId;
- }
-
- // if this happens to be a boolean field, the value is encoded in the type
- if (type == TCType_BOOLEAN_TRUE ||
- type == TCType_BOOLEAN_FALSE)
- {
- // save the boolean value in a special instance variable.
- _booleanValue = [NSNumber numberWithBool:type == TCType_BOOLEAN_TRUE];
- }
-
- // push the new field onto the field stack so we can keep the deltas going.
- _lastFieldId = fieldId;
-
- return YES;
-}
-
--(BOOL) readMapBeginReturningKeyType:(SInt32 *)pkeyType
- valueType:(SInt32 *)pvalueType
- size:(SInt32 *)psize
- error:(NSError *__autoreleasing *)error
-{
- UInt8 keyAndValueType = 0;
- UInt32 size;
- if (![self readVarint32:&size error:error]) {
- return NO;
- }
- if (size != 0) {
- if (![self readByte:&keyAndValueType error:error]) {
- return NO;
- }
- }
-
- UInt8 keyType;
- if (![self ttype:&keyType forCompactType:keyAndValueType >> 4 error:error]) {
- return NO;
- }
-
- UInt8 valueType;
- if (![self ttype:&valueType forCompactType:keyAndValueType & 0xf error:error]) {
- return NO;
- }
-
- if (pkeyType != NULL) {
- *pkeyType = keyType;
- }
- if (pvalueType != NULL) {
- *pvalueType = valueType;
- }
- if (psize != NULL) {
- *psize = size;
- }
-
- return YES;
-}
-
--(BOOL) readListBeginReturningElementType:(SInt32 *)pelementType
- size:(SInt32 *)psize
- error:(NSError *__autoreleasing *)error
-{
- UInt8 sizeAndType;
- if (![self readByte:&sizeAndType error:error]) {
- return NO;
- }
-
- UInt32 size = (sizeAndType >> 4) & 0x0f;
- if (size == 15) {
- if (![self readVarint32:&size error:error]) {
- return NO;
- }
- }
-
- UInt8 elementType;
- if (![self ttype:&elementType forCompactType:sizeAndType & 0x0f error:error]) {
- return NO;
- }
-
- if (pelementType != NULL) {
- *pelementType = elementType;
- }
- if (psize != NULL) {
- *psize = size;
- }
-
- return YES;
-}
-
--(BOOL) readSetBeginReturningElementType:(SInt32 *)pelementType
- size:(SInt32 *)psize
- error:(NSError *__autoreleasing *)error
-{
- return [self readListBeginReturningElementType:pelementType size:psize error:error];
-}
-
--(BOOL) readBool:(BOOL *)value error:(NSError *__autoreleasing *)error
-{
- if (_booleanValue != nil) {
-
- BOOL result = _booleanValue.boolValue;
- _booleanValue = nil;
-
- *value = result;
- }
- else {
-
- UInt8 result;
- if (![self readByte:&result error:error]) {
- return NO;
- }
-
- *value = result == TCType_BOOLEAN_TRUE;
- }
-
- return YES;
-}
-
--(BOOL) readByte:(UInt8 *)value error:(NSError *__autoreleasing *)error
-{
- if (![_transport readAll:value offset:0 length:1 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
- }
- return YES;
-}
-
--(BOOL) readI16:(SInt16 *)value error:(NSError *__autoreleasing *)error
-{
- UInt32 v;
- if (![self readVarint32:&v error:error]) {
- return NO;
- }
-
- if (value) {
- *value = (SInt16)[self zigZagToi32:v];
- }
-
- return YES;
-}
-
--(BOOL) readI32:(SInt32 *)value error:(NSError *__autoreleasing *)error
-{
- UInt32 v;
- if (![self readVarint32:&v error:error]) {
- return NO;
- }
-
- if (value) {
- *value = [self zigZagToi32:v];
- }
-
- return YES;
-}
-
--(BOOL) readI64:(SInt64 *)value error:(NSError *__autoreleasing *)error
-{
- UInt64 v;
- if (![self readVarint64:&v error:error]) {
- return NO;
- }
-
- if (value) {
- *value = [self zigZagToi64:v];
- }
-
- return YES;
-}
-
--(BOOL) readDouble:(double *)value error:(NSError *__autoreleasing *)error
-{
- UInt64 bits;
- if (![_transport readAll:(UInt8 *)&bits offset:0 length:8 error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
- }
-
- bits = OSSwapLittleToHostInt64(bits);
-
- if (value) {
- memcpy(value, &bits, sizeof(bits));
- }
-
- return YES;
-}
-
--(BOOL) readString:(NSString *__autoreleasing *)value error:(NSError *__autoreleasing *)error
-{
- UInt32 length;
- if (![self readVarint32:&length error:error]) {
- return NO;
- }
-
- NSString *result;
-
- if (length != 0) {
-
- NSData *data;
- if (![self readBinaryOfLength:length data:&data error:error]) {
- return NO;
- }
-
- result = [[NSString alloc] initWithData:data
- encoding:NSUTF8StringEncoding];
- }
- else {
- result = @"";
- }
-
- if (value) {
- *value = result;
- }
-
- return YES;
-}
-
--(BOOL) readBinary:(NSData *__autoreleasing *)value error:(NSError *__autoreleasing *)error
-{
- UInt32 length;
- if (![self readVarint32:&length error:error]) {
- return NO;
- }
-
- return [self readBinaryOfLength:length data:value error:error];
-}
-
--(BOOL) readBinaryOfLength:(UInt32)length data:(NSData *__autoreleasing *)value error:(NSError *__autoreleasing *)error
-{
- NSData *result;
-
- if (length != 0) {
-
- NSMutableData *buf = [NSMutableData dataWithLength:length];
- if (![_transport readAll:buf.mutableBytes offset:0 length:length error:error]) {
- PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
- }
-
- result = buf;
- }
- else {
-
- result = [NSData data];
-
- }
-
- if (value) {
- *value = result;
- }
-
- return YES;
-}
-
--(BOOL) readMessageEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
--(BOOL) readFieldEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
--(BOOL) readMapEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
--(BOOL) readListEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
--(BOOL) readSetEnd:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
--(BOOL) readVarint32:(UInt32 *)value error:(NSError *__autoreleasing *)error
-{
- UInt32 result = 0;
- int shift = 0;
-
- while (true) {
-
- UInt8 byte;
- if (![self readByte:&byte error:error]) {
- return NO;
- }
-
- result |= (UInt32)(byte & 0x7f) << shift;
- if (!(byte & 0x80)) {
- break;
- }
-
- shift += 7;
- }
-
- if (value) {
- *value = result;
- }
-
- return YES;
-}
-
--(BOOL) readVarint64:(UInt64 *)value error:(NSError *__autoreleasing *)error
-{
- int shift = 0;
- UInt64 result = 0;
-
- while (true) {
-
- UInt8 byte;
- if (![self readByte:&byte error:error]) {
- return NO;
- }
-
- result |= (UInt64)(byte & 0x7f) << shift;
- if (!(byte & 0x80)) {
- break;
- }
-
- shift += 7;
- }
-
- if (value) {
- *value = result;
- }
-
- return YES;
-}
-
--(SInt32) zigZagToi32:(UInt32)n
-{
- return (SInt32)(n >> 1) ^ (-(SInt32)(n & 1));
-}
-
--(SInt64) zigZagToi64:(UInt64)n
-{
- return (SInt64)(n >> 1) ^ (-(SInt64)(n & 1));
-}
-
--(BOOL) ttype:(UInt8 *)ttype forCompactType:(UInt8)ctype error:(NSError *__autoreleasing *)error
-{
- switch (ctype & 0x0f) {
- case TCType_STOP:
- *ttype = TTypeSTOP;
- return YES;
-
- case TCType_BOOLEAN_FALSE:
- case TCType_BOOLEAN_TRUE:
- *ttype = TTypeBOOL;
- return YES;
-
- case TCType_BYTE:
- *ttype = TTypeBYTE;
- return YES;
-
- case TCType_I16:
- *ttype = TTypeI16;
- return YES;
-
- case TCType_I32:
- *ttype = TTypeI32;
- return YES;
-
- case TCType_I64:
- *ttype = TTypeI64;
- return YES;
-
- case TCType_DOUBLE:
- *ttype = TTypeDOUBLE;
- return YES;
-
- case TCType_BINARY:
- *ttype = TTypeSTRING;
- return YES;
-
- case TCType_LIST:
- *ttype = TTypeLIST;
- return YES;
-
- case TCType_SET:
- *ttype = TTypeSET;
- return YES;
-
- case TCType_MAP:
- *ttype = TTypeMAP;
- return YES;
-
- case TCType_STRUCT:
- *ttype = TTypeSTRUCT;
- return YES;
-
- default:
- if (error) {
- *error = [NSError errorWithDomain:TProtocolErrorDomain
- code:TProtocolErrorUnknown
- userInfo:@{TProtocolErrorTypeKey: @((UInt8)(ctype & 0x0F))}];
- }
- return NO;
- }
-}
-
--(UInt8) compactTypeForTType:(UInt8)ttype
-{
- static UInt8 ttypeToCompactType[] = {
- [TTypeSTOP] = TCType_STOP,
- [TTypeBOOL] = TCType_BOOLEAN_FALSE,
- [TTypeBYTE] = TCType_BYTE,
- [TTypeDOUBLE] = TCType_DOUBLE,
- [TTypeI16] = TCType_I16,
- [TTypeI32] = TCType_I32,
- [TTypeI64] = TCType_I64,
- [TTypeSTRING] = TCType_BINARY,
- [TTypeSTRUCT] = TCType_STRUCT,
- [TTypeMAP] = TCType_MAP,
- [TTypeSET] = TCType_SET,
- [TTypeLIST] = TCType_LIST
- };
-
- return ttypeToCompactType[ttype];
-}
-
-@end
diff --git a/lib/cocoa/src/protocol/TMultiplexedProtocol.h b/lib/cocoa/src/protocol/TMultiplexedProtocol.h
deleted file mode 100644
index b8ce361..0000000
--- a/lib/cocoa/src/protocol/TMultiplexedProtocol.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-
-#import "TProtocolDecorator.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-extern NSString *TMultiplexedProtocolSeperator;
-
-
-@interface TMultiplexedProtocol : TProtocolDecorator
-
--(id) initWithProtocol:(id <TProtocol>)protocol
- serviceName:(NSString *)name;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
\ No newline at end of file
diff --git a/lib/cocoa/src/protocol/TMultiplexedProtocol.m b/lib/cocoa/src/protocol/TMultiplexedProtocol.m
deleted file mode 100644
index 5838c57..0000000
--- a/lib/cocoa/src/protocol/TMultiplexedProtocol.m
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.
- */
-
-#import "TMultiplexedProtocol.h"
-
-#import "TProtocol.h"
-
-NSString *TMultiplexedProtocolSeperator = @":";
-
-
-@interface TMultiplexedProtocol ()
-
-@property(strong, nonatomic) NSString *serviceName;
-
-@end
-
-
-@implementation TMultiplexedProtocol
-
--(id) initWithProtocol:(id <TProtocol>)protocol
- serviceName:(NSString *)name
-{
- self = [super initWithProtocol:protocol];
- if (self) {
- _serviceName = name;
- }
- return self;
-}
-
--(BOOL) writeMessageBeginWithName:(NSString *)name
- type:(SInt32)messageType
- sequenceID:(SInt32)sequenceID
- error:(NSError *__autoreleasing *)error
-{
- switch (messageType) {
- case TMessageTypeCALL:
- case TMessageTypeONEWAY: {
- NSMutableString *serviceFunction = [[NSMutableString alloc] initWithString:_serviceName];
- [serviceFunction appendString:TMultiplexedProtocolSeperator];
- [serviceFunction appendString:name];
- return [super writeMessageBeginWithName:serviceFunction type:messageType sequenceID:sequenceID error:error];
- }
- break;
-
- default:
- return [super writeMessageBeginWithName:name type:messageType sequenceID:sequenceID error:error];
- }
-}
-
-@end
diff --git a/lib/cocoa/src/protocol/TProtocol.h b/lib/cocoa/src/protocol/TProtocol.h
deleted file mode 100644
index 841059f..0000000
--- a/lib/cocoa/src/protocol/TProtocol.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-
-#import "TTransport.h"
-
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-typedef NS_ENUM (int, TMessageType) {
- TMessageTypeCALL = 1,
- TMessageTypeREPLY = 2,
- TMessageTypeEXCEPTION = 3,
- TMessageTypeONEWAY = 4
-};
-
-typedef NS_ENUM (int, TType) {
- TTypeSTOP = 0,
- TTypeVOID = 1,
- TTypeBOOL = 2,
- TTypeBYTE = 3,
- TTypeDOUBLE = 4,
- TTypeI16 = 6,
- TTypeI32 = 8,
- TTypeI64 = 10,
- TTypeSTRING = 11,
- TTypeSTRUCT = 12,
- TTypeMAP = 13,
- TTypeSET = 14,
- TTypeLIST = 15
-};
-
-
-@protocol TProtocol <NSObject>
-
--(id <TTransport>) transport;
-
--(BOOL) readMessageBeginReturningName:(NSString *__nullable __autoreleasing *__nullable)name
- type:(nullable SInt32 *)type
- sequenceID:(nullable SInt32 *)sequenceID
- error:(NSError *__autoreleasing *)error;
--(BOOL) readMessageEnd:(NSError *__autoreleasing *)error;
-
--(BOOL) readStructBeginReturningName:(NSString *__nullable __autoreleasing *__nullable)name
- error:(NSError *__autoreleasing *)error;
--(BOOL) readStructEnd:(NSError *__autoreleasing *)error;
-
--(BOOL) readFieldBeginReturningName:(NSString *__nullable __autoreleasing *__nullable)name
- type:(SInt32 *)fieldType
- fieldID:(nullable SInt32 *)fieldID
- error:(NSError *__autoreleasing *)error;
--(BOOL) readFieldEnd:(NSError *__autoreleasing *)error;
-
--(BOOL) readString:(NSString *__nonnull __autoreleasing *__nonnull)value error:(NSError **)error;
-
--(BOOL) readBool:(BOOL *)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) readByte:(UInt8 *)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) readI16:(SInt16 *)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) readI32:(SInt32 *)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) readI64:(SInt64 *)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) readDouble:(double *)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) readBinary:(NSData *__nonnull __autoreleasing *__nonnull)value error:(NSError **)error;
-
--(BOOL) readMapBeginReturningKeyType:(nullable SInt32 *)keyType
- valueType:(nullable SInt32 *)valueType
- size:(SInt32 *)size
- error:(NSError *__autoreleasing *)error;
--(BOOL) readMapEnd:(NSError *__autoreleasing *)error;
-
-
--(BOOL) readSetBeginReturningElementType:(nullable SInt32 *)elementType
- size:(SInt32 *)size
- error:(NSError *__autoreleasing *)error;
--(BOOL) readSetEnd:(NSError *__autoreleasing *)error;
-
-
--(BOOL) readListBeginReturningElementType:(nullable SInt32 *)elementType
- size:(SInt32 *)size
- error:(NSError *__autoreleasing *)error;
--(BOOL) readListEnd:(NSError *__autoreleasing *)error;
-
-
--(BOOL) writeMessageBeginWithName:(NSString *)name
- type:(SInt32)messageType
- sequenceID:(SInt32)sequenceID
- error:(NSError *__autoreleasing *)error;
--(BOOL) writeMessageEnd:(NSError *__autoreleasing *)error;
-
--(BOOL) writeStructBeginWithName:(NSString *)name error:(NSError **)error;
--(BOOL) writeStructEnd:(NSError *__autoreleasing *)error;
-
--(BOOL) writeFieldBeginWithName:(NSString *)name
- type:(SInt32)fieldType
- fieldID:(SInt32)fieldID
- error:(NSError *__autoreleasing *)error;
-
--(BOOL) writeI32:(SInt32)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) writeI64:(SInt64)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) writeI16:(short)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) writeByte:(UInt8)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) writeString:(NSString *)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) writeDouble:(double)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) writeBool:(BOOL)value error:(NSError *__autoreleasing *)error;
-
--(BOOL) writeBinary:(NSData *)data error:(NSError *__autoreleasing *)error;
-
--(BOOL) writeFieldStop:(NSError *__autoreleasing *)error;
-
--(BOOL) writeFieldEnd:(NSError *__autoreleasing *)error;
-
--(BOOL) writeMapBeginWithKeyType:(SInt32)keyType
- valueType:(SInt32)valueType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error;
--(BOOL) writeMapEnd:(NSError *__autoreleasing *)error;
-
-
--(BOOL) writeSetBeginWithElementType:(SInt32)elementType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error;
--(BOOL) writeSetEnd:(NSError *__autoreleasing *)error;
-
-
--(BOOL) writeListBeginWithElementType:(SInt32)elementType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error;
-
--(BOOL) writeListEnd:(NSError *__autoreleasing *)error;
-
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/protocol/TProtocolDecorator.h b/lib/cocoa/src/protocol/TProtocolDecorator.h
deleted file mode 100644
index 369b6a2..0000000
--- a/lib/cocoa/src/protocol/TProtocolDecorator.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-
-#import "TProtocol.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@interface TProtocolDecorator : NSObject <TProtocol>
-
--(id) initWithProtocol:(id <TProtocol>)protocol;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
\ No newline at end of file
diff --git a/lib/cocoa/src/protocol/TProtocolDecorator.m b/lib/cocoa/src/protocol/TProtocolDecorator.m
deleted file mode 100644
index 218f900..0000000
--- a/lib/cocoa/src/protocol/TProtocolDecorator.m
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * 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.
- */
-
-#import "TProtocolDecorator.h"
-
-
-@interface TProtocolDecorator ()
-
-@property(strong, nonatomic) id<TProtocol> concreteProtocol;
-
-@end
-
-
-@implementation TProtocolDecorator
-
--(id) initWithProtocol:(id <TProtocol>)protocol
-{
- self = [super init];
- if (self) {
- _concreteProtocol = protocol;
- }
- return self;
-}
-
--(id <TTransport>) transport
-{
- return [_concreteProtocol transport];
-}
-
--(BOOL) readMessageBeginReturningName:(NSString **)name
- type:(SInt32 *)type
- sequenceID:(SInt32 *)sequenceID
- error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readMessageBeginReturningName:name
- type:type
- sequenceID:sequenceID
- error:error];
-}
-
--(BOOL) readMessageEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readMessageEnd:error];
-}
-
--(BOOL) readStructBeginReturningName:(NSString **)name
- error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readStructBeginReturningName:name error:error];
-}
-
--(BOOL) readStructEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readStructEnd:error];
-}
-
--(BOOL) readFieldBeginReturningName:(NSString **)name
- type:(SInt32 *)fieldType
- fieldID:(SInt32 *)fieldID
- error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readFieldBeginReturningName:name
- type:fieldType
- fieldID:fieldID
- error:error];
-}
--(BOOL) readFieldEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readFieldEnd:error];
-}
-
--(BOOL) readString:(NSString *__autoreleasing *)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readString:value error:error];
-}
-
--(BOOL) readBool:(BOOL *)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readBool:value error:error];
-}
-
--(BOOL) readByte:(UInt8 *)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readByte:value error:error];
-}
-
--(BOOL) readI16:(SInt16 *)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readI16:value error:error];
-}
-
--(BOOL) readI32:(SInt32 *)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readI32:value error:error];
-}
-
--(BOOL) readI64:(SInt64 *)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readI64:value error:error];
-}
-
--(BOOL) readDouble:(double *)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readDouble:value error:error];
-}
-
--(BOOL) readBinary:(NSData *__autoreleasing *)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readBinary:value error:error];
-}
-
--(BOOL) readMapBeginReturningKeyType:(SInt32 *)keyType
- valueType:(SInt32 *)valueType
- size:(SInt32 *)size
- error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readMapBeginReturningKeyType:keyType
- valueType:valueType
- size:size
- error:error];
-}
--(BOOL) readMapEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readMapEnd:error];
-}
-
-
--(BOOL) readSetBeginReturningElementType:(SInt32 *)elementType
- size:(SInt32 *)size
- error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readSetBeginReturningElementType:elementType
- size:size
- error:error];
-}
--(BOOL) readSetEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readSetEnd:error];
-}
-
--(BOOL) readListBeginReturningElementType:(SInt32 *)elementType
- size:(SInt32 *)size
- error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readListBeginReturningElementType:elementType
- size:size
- error:error];
-}
--(BOOL) readListEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol readListEnd:error];
-}
-
--(BOOL) writeMessageBeginWithName:(NSString *)name
- type:(SInt32)messageType
- sequenceID:(SInt32)sequenceID
- error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeMessageBeginWithName:name
- type:messageType
- sequenceID:sequenceID
- error:error];
-}
--(BOOL) writeMessageEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeMessageEnd:error];
-}
-
--(BOOL) writeStructBeginWithName:(NSString *)name error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeStructBeginWithName:name error:error];
-}
--(BOOL) writeStructEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeStructEnd:error];
-}
-
--(BOOL) writeFieldBeginWithName:(NSString *)name
- type:(SInt32)fieldType
- fieldID:(SInt32)fieldID
- error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeFieldBeginWithName:name
- type:fieldType
- fieldID:fieldID
- error:error];
-}
-
--(BOOL) writeI32:(SInt32)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeI32:value error:error];
-}
-
--(BOOL) writeI64:(SInt64)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeI64:value error:error];
-}
-
--(BOOL) writeI16:(SInt16)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeI16:value error:error];
-}
-
--(BOOL) writeByte:(UInt8)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeByte:value error:error];
-}
-
--(BOOL) writeString:(NSString *)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeString:value error:error];
-}
-
--(BOOL) writeDouble:(double)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeDouble:value error:error];
-}
-
--(BOOL) writeBool:(BOOL)value error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeBool:value error:error];
-}
-
--(BOOL) writeBinary:(NSData *)data error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeBinary:data error:error];
-}
-
--(BOOL) writeFieldStop:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeFieldStop:error];
-}
-
--(BOOL) writeFieldEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeFieldEnd:error];
-}
-
--(BOOL) writeMapBeginWithKeyType:(SInt32)keyType
- valueType:(SInt32)valueType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeMapBeginWithKeyType:keyType
- valueType:valueType
- size:size
- error:error];
-}
-
--(BOOL) writeMapEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeMapEnd:error];
-}
-
--(BOOL) writeSetBeginWithElementType:(SInt32)elementType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeSetBeginWithElementType:elementType size:size error:error];
-}
-
--(BOOL) writeSetEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeSetEnd:error];
-}
-
--(BOOL) writeListBeginWithElementType:(SInt32)elementType
- size:(SInt32)size
- error:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeListBeginWithElementType:elementType size:size error:error];
-}
-
--(BOOL) writeListEnd:(NSError *__autoreleasing *)error
-{
- return [_concreteProtocol writeListEnd:error];
-}
-
-@end
diff --git a/lib/cocoa/src/protocol/TProtocolError.h b/lib/cocoa/src/protocol/TProtocolError.h
deleted file mode 100644
index ab0bc40..0000000
--- a/lib/cocoa/src/protocol/TProtocolError.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.
- */
-
-#import "TError.h"
-
-
-extern NSString *TProtocolErrorDomain;
-
-typedef NS_ENUM (int, TProtocolError) {
- TProtocolErrorUnknown = 0,
- TProtocolErrorInvalidData = 1,
- TProtocolErrorNegativeSize = 2,
- TProtocolErrorSizeLimit = 3,
- TProtocolErrorBadVersion = 4,
- TProtocolErrorNotImplemented = 5,
- TProtocolErrorDepthLimit = 6,
-};
-
-
-typedef NS_ENUM(int, TProtocolExtendedError) {
- TProtocolExtendedErrorMissingRequiredField = 1001,
- TProtocolExtendedErrorUnexpectedType = 1002,
- TProtocolExtendedErrorMismatchedProtocol = 1003,
-};
-
-extern NSString *TProtocolErrorExtendedErrorKey;
-extern NSString *TProtocolErrorFieldNameKey;
-extern NSString *TProtocolErrorExpectedIdKey;
-extern NSString *TProtocolErrorExpectedVersionKey;
-extern NSString *TProtocolErrorTypeKey;
-extern NSString *TProtocolErrorSourceLineKey;
-extern NSString *TProtocolErrorSourceFileKey;
-extern NSString *TProtocolErrorSourceMethodKey;
-extern NSString *TProtocolErrorMessageNameKey;
-
-
-#define PROTOCOL_ERROR(ret, err, ...) \
- if (error) { \
- *error = [NSError errorWithDomain:TProtocolErrorDomain \
- code:TProtocolError ## err \
- userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:__VA_ARGS__], \
- @"SourceFile": [NSString stringWithUTF8String:__FILE__], \
- @"SourceLine": @(__LINE__), \
- @"SourceFunction": [NSString stringWithUTF8String:__PRETTY_FUNCTION__], \
- @"Message": self.currentMessageName ? self.currentMessageName : @""}]; \
- } \
- return ret
-
-#define PROTOCOL_TRANSPORT_ERROR(ret, errorPtr, ...) \
- if (errorPtr) { \
- *error = [NSError errorWithDomain:TProtocolErrorDomain \
- code:TProtocolErrorUnknown \
- userInfo:@{NSLocalizedDescriptionKey: [[NSString stringWithFormat:__VA_ARGS__] stringByAppendingFormat:@": %@", [(*errorPtr) localizedDescription]], \
- TProtocolErrorSourceFileKey: [NSString stringWithUTF8String:__FILE__], \
- TProtocolErrorSourceLineKey: @(__LINE__), \
- TProtocolErrorSourceMethodKey: [NSString stringWithUTF8String:__PRETTY_FUNCTION__], \
- TProtocolErrorMessageNameKey: self.currentMessageName ? self.currentMessageName : @"", \
- NSUnderlyingErrorKey: *errorPtr}]; \
- } \
- return ret
diff --git a/lib/cocoa/src/protocol/TProtocolError.m b/lib/cocoa/src/protocol/TProtocolError.m
deleted file mode 100644
index 953673b..0000000
--- a/lib/cocoa/src/protocol/TProtocolError.m
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.
- */
-
-#import "TProtocolError.h"
-
-
-NSString *TProtocolErrorDomain = @"TProtocolErrorDomain";
-
-NSString *TProtocolErrorExtendedErrorKey = @"extendedError";
-NSString *TProtocolErrorFieldNameKey = @"field";
-NSString *TProtocolErrorExpectedIdKey = @"expectedId";
-NSString *TProtocolErrorExpectedVersionKey = @"expectedVersion";
-NSString *TProtocolErrorTypeKey = @"type";
-NSString *TProtocolErrorSourceLineKey = @"sourceLine";
-NSString *TProtocolErrorSourceFileKey = @"sourceFile";
-NSString *TProtocolErrorSourceMethodKey = @"sourceMethod";
-NSString *TProtocolErrorMessageNameKey = @"messageName";
diff --git a/lib/cocoa/src/protocol/TProtocolFactory.h b/lib/cocoa/src/protocol/TProtocolFactory.h
deleted file mode 100644
index a022a7f..0000000
--- a/lib/cocoa/src/protocol/TProtocolFactory.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TProtocol.h"
-#import "TTransport.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@protocol TProtocolFactory <NSObject>
-
-@property (readonly, nonatomic) NSString *protocolName;
-
--(id<TProtocol>) newProtocolOnTransport:(id<TTransport>)transport;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/protocol/TProtocolUtil.h b/lib/cocoa/src/protocol/TProtocolUtil.h
deleted file mode 100644
index 82510cf..0000000
--- a/lib/cocoa/src/protocol/TProtocolUtil.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.
- */
-
-#import "TProtocol.h"
-#import "TTransport.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@interface TProtocolUtil : NSObject
-
-+(BOOL) skipType:(int)type onProtocol:(id <TProtocol>)protocol error:(NSError **)error;
-
-@end;
-
-
-NS_ASSUME_NONNULL_END
\ No newline at end of file
diff --git a/lib/cocoa/src/protocol/TProtocolUtil.m b/lib/cocoa/src/protocol/TProtocolUtil.m
deleted file mode 100644
index c0d65ac..0000000
--- a/lib/cocoa/src/protocol/TProtocolUtil.m
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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.
- */
-
-#import "TProtocolUtil.h"
-
-@implementation TProtocolUtil
-
-+(BOOL) skipType:(int)type onProtocol:(id <TProtocol>)protocol error:(NSError **)error
-{
- switch (type) {
- case TTypeBOOL: {
- BOOL val;
- if (![protocol readBool:&val error:error]) {
- return NO;
- }
- }
- break;
-
- case TTypeBYTE: {
- UInt8 val;
- if (![protocol readByte:&val error:error]) {
- return NO;
- }
- }
- break;
-
- case TTypeI16: {
- SInt16 val;
- if (![protocol readI16:&val error:error]) {
- return NO;
- }
- }
- break;
-
- case TTypeI32: {
- SInt32 val;
- if (![protocol readI32:&val error:error]) {
- return NO;
- }
- }
- break;
-
- case TTypeI64: {
- SInt64 val;
- if (![protocol readI64:&val error:error]) {
- return NO;
- }
- }
- break;
-
- case TTypeDOUBLE: {
- double val;
- if (![protocol readDouble:&val error:error]) {
- return NO;
- }
- }
- break;
-
- case TTypeSTRING: {
- NSString *val;
- if (![protocol readString:&val error:error]) {
- return NO;
- }
- }
- break;
-
- case TTypeSTRUCT: {
- if (![protocol readStructBeginReturningName:NULL error:error]) {
- return NO;
- }
- while (true) {
- SInt32 fieldType;
- if (![protocol readFieldBeginReturningName:nil type:&fieldType fieldID:nil error:error]) {
- return NO;
- }
- if (fieldType == TTypeSTOP) {
- break;
- }
- if (![self skipType:fieldType onProtocol:protocol error:error]) {
- return NO;
- }
- if (![protocol readFieldEnd:error]) {
- return NO;
- }
- }
- if (![protocol readStructEnd:error]) {
- return NO;
- }
- }
- break;
-
- case TTypeMAP: {
- SInt32 keyType;
- SInt32 valueType;
- SInt32 size;
- if (![protocol readMapBeginReturningKeyType:&keyType valueType:&valueType size:&size error:error]) {
- return NO;
- }
- int i;
- for (i = 0; i < size; i++) {
- if (![TProtocolUtil skipType:keyType onProtocol:protocol error:error]) {
- return NO;
- }
- if (![TProtocolUtil skipType:valueType onProtocol:protocol error:error]) {
- return NO;
- }
- }
- if (![protocol readMapEnd:error]) {
- return NO;
- }
- }
- break;
-
- case TTypeSET: {
- SInt32 elemType;
- SInt32 size;
- if (![protocol readSetBeginReturningElementType:&elemType size:&size error:error]) {
- return NO;
- }
- int i;
- for (i = 0; i < size; i++) {
- if (![TProtocolUtil skipType:elemType onProtocol:protocol error:error]) {
- return NO;
- }
- }
- if (![protocol readSetEnd:error]) {
- return NO;
- }
- }
- break;
-
- case TTypeLIST: {
- SInt32 elemType;
- SInt32 size;
- if (![protocol readListBeginReturningElementType:&elemType size:&size error:error]) {
- return NO;
- }
- int i;
- for (i = 0; i < size; i++) {
- if (![TProtocolUtil skipType:elemType onProtocol:protocol error:error]) {
- return NO;
- }
- }
- if (![protocol readListEnd:error]) {
- return NO;
- }
- }
- break;
-
- }
-
- return YES;
-}
-
-@end
diff --git a/lib/cocoa/src/server/TSocketServer.h b/lib/cocoa/src/server/TSocketServer.h
deleted file mode 100644
index 95b0d3c..0000000
--- a/lib/cocoa/src/server/TSocketServer.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TProtocolFactory.h"
-#import "TProcessorFactory.h"
-
-#if !TARGET_OS_IPHONE
-#import <CoreServices/CoreServices.h>
-#else
-#import <CFNetwork/CFNetwork.h>
-#endif
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-extern NSString *const TSocketServerClientConnectionFinished;
-extern NSString *const TSocketServerProcessorKey;
-extern NSString *const TSockerServerTransportKey;
-
-
-@interface TSocketServer : NSObject
-
--(instancetype) initWithPort:(int)port
- protocolFactory:(id <TProtocolFactory>)protocolFactory
- processorFactory:(id <TProcessorFactory>)processorFactory;
-
-- (instancetype) initWithPath: (NSString *) path
- protocolFactory: (id <TProtocolFactory>) protocolFactory
- processorFactory: (id <TProcessorFactory>) processorFactory;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/server/TSocketServer.m b/lib/cocoa/src/server/TSocketServer.m
deleted file mode 100644
index 09b603c..0000000
--- a/lib/cocoa/src/server/TSocketServer.m
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TSocketServer.h"
-#import "TNSFileHandleTransport.h"
-#import "TProtocol.h"
-#import "TTransportError.h"
-
-#import <sys/socket.h>
-#include <netinet/in.h>
-#include <sys/un.h>
-
-
-NSString *const TSocketServerClientConnectionFinished = @"TSocketServerClientConnectionFinished";
-NSString *const TSocketServerProcessorKey = @"TSocketServerProcessor";
-NSString *const TSockerServerTransportKey = @"TSockerServerTransport";
-
-
-@interface TSocketServer ()
-
-@property(strong, nonatomic) id<TProtocolFactory> inputProtocolFactory;
-@property(strong, nonatomic) id<TProtocolFactory> outputProtocolFactory;
-@property(strong, nonatomic) id<TProcessorFactory> processorFactory;
-@property(strong, nonatomic) NSFileHandle *socketFileHandle;
-@property(strong, nonatomic) dispatch_queue_t processingQueue;
-@property(strong, nonatomic) NSString *domainSocketPath;
-
-@end
-
-
-@implementation TSocketServer
-
--(instancetype) initWithSocket:(CFSocketRef)socket
- protocolFactory:(id <TProtocolFactory>)protocolFactory
- processorFactory:(id <TProcessorFactory>)processorFactory;
-{
- self = [super init];
-
- _inputProtocolFactory = protocolFactory;
- _outputProtocolFactory = protocolFactory;
- _processorFactory = processorFactory;
-
- dispatch_queue_attr_t processingQueueAttr =
- dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_BACKGROUND, 0);
-
- _processingQueue = dispatch_queue_create("TSocketServer.processing", processingQueueAttr);
-
- // create a socket.
- int fd = CFSocketGetNative(socket);
-
- // wrap it in a file handle so we can get messages from it
- _socketFileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fd
- closeOnDealloc:YES];
-
- // throw away our socket
- CFSocketInvalidate(socket);
- CFRelease(socket);
-
- // register for notifications of accepted incoming connections
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(connectionAccepted:)
- name:NSFileHandleConnectionAcceptedNotification
- object:_socketFileHandle];
-
- // tell socket to listen
- [_socketFileHandle acceptConnectionInBackgroundAndNotify];
-
- return self;
-}
-
-- (id) initWithPort: (int) port
- protocolFactory: (id <TProtocolFactory>) protocolFactory
- processorFactory: (id <TProcessorFactory>) processorFactory
-{
- CFSocketRef socket = [[self class] createSocketWithPort:port];
- if (socket == NULL) {
- return nil;
- }
-
- if (self = [self initWithSocket:socket protocolFactory:protocolFactory processorFactory:processorFactory]) {
- NSLog(@"TSocketServer: Listening on TCP port %d", port);
- }
- return self;
-}
-
-
-+(CFSocketRef) createSocketWithPort:(int)port
-{
- CFSocketRef socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL);
- if (socket) {
- CFSocketSetSocketFlags(socket, CFSocketGetSocketFlags(socket) & ~kCFSocketCloseOnInvalidate);
- int fd = CFSocketGetNative(socket);
- int yes = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));
-
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_len = sizeof(addr);
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- NSData *address = [NSData dataWithBytes:&addr length:sizeof(addr)];
- if (CFSocketSetAddress(socket, (__bridge CFDataRef)address) != kCFSocketSuccess) {
- CFSocketInvalidate(socket);
- CFRelease(socket);
- NSLog(@"TSocketServer: Could not bind to address");
- return NULL;
- }
-
- return socket;
- }
- else {
- NSLog(@"TSocketServer: No server socket");
- return NULL;
- }
-}
-
-- (id) initWithPath: (NSString *) path
- protocolFactory: (id <TProtocolFactory>) protocolFactory
- processorFactory: (id <TProcessorFactory>) processorFactory
-{
- _domainSocketPath = path;
- CFSocketRef socket = [[self class] createSocketWithPath:path];
- if (socket == NULL) {
- return nil;
- }
-
- if (self = [self initWithSocket:socket protocolFactory:protocolFactory processorFactory:processorFactory]) {
- NSLog(@"TSocketServer: Listening on path %@", path);
- }
- return self;
-}
-
-+ (CFSocketRef) createSocketWithPath: (NSString *) path
-{
- CFSocketRef socket = CFSocketCreate(kCFAllocatorDefault, PF_LOCAL, SOCK_STREAM, IPPROTO_IP, 0, NULL, NULL);
- if (socket) {
- CFSocketSetSocketFlags(socket, CFSocketGetSocketFlags(socket) & ~kCFSocketCloseOnInvalidate);
- int fd = CFSocketGetNative(socket);
- int yes = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));
-
- size_t nullTerminatedPathLength = path.length + 1;
- struct sockaddr_un addr;
- if (nullTerminatedPathLength> sizeof(addr.sun_path)) {
- NSLog(@"TSocketServer: Unable to create socket at path %@. Path is too long.", path);
- return NULL;
- }
-
- addr.sun_family = AF_LOCAL;
- memcpy(addr.sun_path, path.UTF8String, nullTerminatedPathLength);
- addr.sun_len = SUN_LEN(&addr);
-
- NSData *address = [NSData dataWithBytes:&addr length:sizeof(addr)];
- if (CFSocketSetAddress(socket, (__bridge CFDataRef)address) != kCFSocketSuccess) {
- CFSocketInvalidate(socket);
- CFRelease(socket);
- NSLog(@"TSocketServer: Could not bind to address");
- return NULL;
- }
-
- return socket;
- } else {
- NSLog(@"TSocketServer: No server socket");
- return NULL;
- }
-}
-
--(void) dealloc
-{
- [[NSNotificationCenter defaultCenter] removeObserver:self];
-
- if (_domainSocketPath != nil) {
- unlink(_domainSocketPath.UTF8String);
- }
-}
-
-
--(void) connectionAccepted:(NSNotification *)notification
-{
- NSFileHandle *socket = [notification.userInfo objectForKey:NSFileHandleNotificationFileHandleItem];
-
- // Now that we have a client connected, handle request on queue
- dispatch_async(_processingQueue, ^{
-
- [self handleClientConnection:socket];
-
- });
-
- // Continue accepting connections
- [_socketFileHandle acceptConnectionInBackgroundAndNotify];
-}
-
-
--(void) handleClientConnection:(NSFileHandle *)clientSocket
-{
- @autoreleasepool {
-
- TNSFileHandleTransport *transport = [[TNSFileHandleTransport alloc] initWithFileHandle:clientSocket];
- id<TProcessor> processor = [_processorFactory processorForTransport:transport];
-
- id <TProtocol> inProtocol = [_inputProtocolFactory newProtocolOnTransport:transport];
- id <TProtocol> outProtocol = [_outputProtocolFactory newProtocolOnTransport:transport];
-
- NSError *error;
- if (![processor processOnInputProtocol:inProtocol outputProtocol:outProtocol error:&error]) {
- // Handle error
- NSLog(@"Error processing request: %@", error);
- }
-
- dispatch_async(dispatch_get_main_queue(), ^{
-
- [NSNotificationCenter.defaultCenter postNotificationName:TSocketServerClientConnectionFinished
- object:self
- userInfo:@{TSocketServerProcessorKey: processor,
- TSockerServerTransportKey: transport}];
- });
-
- }
-}
-
-@end
diff --git a/lib/cocoa/src/transport/TAsyncTransport.h b/lib/cocoa/src/transport/TAsyncTransport.h
deleted file mode 100644
index bab4fbd..0000000
--- a/lib/cocoa/src/transport/TAsyncTransport.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.
- */
-
-#import "TTransport.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@protocol TAsyncTransport;
-
-
-@protocol TAsyncTransportFactory <NSObject>
-
--(id<TAsyncTransport>) newTransport;
-
-@end
-
-
-typedef void (^TAsyncCompletionBlock)();
-typedef void (^TAsyncFailureBlock)(NSError * __nonnull);
-
-
-@protocol TAsyncTransport <TTransport>
-
--(void) flushWithCompletion:(TAsyncCompletionBlock)completed failure:(TAsyncFailureBlock)failure;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
\ No newline at end of file
diff --git a/lib/cocoa/src/transport/TFramedTransport.h b/lib/cocoa/src/transport/TFramedTransport.h
deleted file mode 100644
index ea68ac4..0000000
--- a/lib/cocoa/src/transport/TFramedTransport.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TTransport.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@interface TFramedTransport : NSObject <TTransport>
-
--(id) initWithTransport:(id <TTransport>)transport;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/transport/TFramedTransport.m b/lib/cocoa/src/transport/TFramedTransport.m
deleted file mode 100644
index 4db65c4..0000000
--- a/lib/cocoa/src/transport/TFramedTransport.m
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * 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.
- */
-
-#import "TFramedTransport.h"
-#import "TTransportError.h"
-
-#define HEADER_SIZE 4
-#define INIT_FRAME_SIZE 1024
-
-
-@interface TFramedTransport ()
-
-@property(strong, nonatomic) id<TTransport> transport;
-@property(strong, nonatomic) NSMutableData *writeBuffer;
-@property(strong, nonatomic) NSMutableData *readBuffer;
-@property(assign, nonatomic) NSUInteger readOffset;
-
-@end
-
-
-@implementation TFramedTransport
-
--(id) initWithTransport:(id <TTransport>)aTransport
-{
- if ((self = [self init])) {
- _transport = aTransport;
- _readBuffer = nil;
- _readOffset = 0;
- _writeBuffer = [NSMutableData dataWithLength:HEADER_SIZE];
- }
- return self;
-}
-
--(BOOL) flush:(NSError **)error
-{
- int len = (int)[_writeBuffer length];
- int data_len = len - HEADER_SIZE;
- if (data_len < 0) {
- if (error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorUnknown
- userInfo:@{}];
- }
- return NO;
- }
-
- UInt8 i32rd[HEADER_SIZE];
- i32rd[0] = (UInt8)(0xff & (data_len >> 24));
- i32rd[1] = (UInt8)(0xff & (data_len >> 16));
- i32rd[2] = (UInt8)(0xff & (data_len >> 8));
- i32rd[3] = (UInt8)(0xff & (data_len));
-
- // should we make a copy of the writeBuffer instead? Better for threaded
- // operations!
- [_writeBuffer replaceBytesInRange:NSMakeRange(0, HEADER_SIZE)
- withBytes:i32rd length:HEADER_SIZE];
-
- if (![_transport write:_writeBuffer.mutableBytes offset:0 length:len error:error]) {
- return NO;
- }
-
- if (![_transport flush:error]) {
- return NO;
- }
-
- _writeBuffer.length = HEADER_SIZE;
-
- return YES;
-}
-
--(BOOL) write:(const UInt8 *)data offset:(UInt32)offset length:(UInt32)length error:(NSError *__autoreleasing *)error
-{
- [_writeBuffer appendBytes:data+offset length:length];
-
- return YES;
-}
-
--(BOOL) readAll:(UInt8 *)outBuffer offset:(UInt32)outBufferOffset length:(UInt32)length error:(NSError *__autoreleasing *)error
-{
- UInt32 got = [self readAvail:outBuffer offset:outBufferOffset maxLength:length error:error];
- if (got != length) {
-
- // Report underflow only if readAvail didn't report error already
- if (error && !*error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorEndOfFile
- userInfo:nil];
- }
-
- return NO;
- }
-
- return YES;
-}
-
--(UInt32) readAvail:(UInt8 *)outBuffer offset:(UInt32)outBufferOffset maxLength:(UInt32)length error:(NSError *__autoreleasing *)error
-{
- UInt32 got = 0;
- while (got < length) {
-
- NSUInteger avail = _readBuffer.length - _readOffset;
- if (avail == 0) {
- if (![self readFrame:error]) {
- return 0;
- }
- avail = _readBuffer.length;
- }
-
- NSRange range;
- range.location = _readOffset;
- range.length = MIN(length - got, avail);
-
- [_readBuffer getBytes:outBuffer+outBufferOffset+got range:range];
- _readOffset += range.length;
- got += range.length;
- }
-
- return got;
-}
-
--(BOOL) readFrame:(NSError **)error
-{
- UInt8 i32rd[HEADER_SIZE];
- if (![_transport readAll:i32rd offset:0 length:HEADER_SIZE error:error]) {
- return NO;
- }
-
- SInt32 size =
- ((i32rd[0] & 0xff) << 24) |
- ((i32rd[1] & 0xff) << 16) |
- ((i32rd[2] & 0xff) << 8) |
- ((i32rd[3] & 0xff));
-
- if (_readBuffer == nil) {
-
- _readBuffer = [NSMutableData dataWithLength:size];
-
- }
- else {
-
- SInt32 len = (SInt32)_readBuffer.length;
- if (len >= size) {
-
- _readBuffer.length = size;
-
- }
- else {
-
- // increase length of data buffer
- [_readBuffer increaseLengthBy:size-len];
-
- }
-
- }
-
- // copy into internal memory buffer
- if (![_transport readAll:_readBuffer.mutableBytes offset:0 length:size error:error]) {
- return NO;
- }
-
- return YES;
-}
-
-@end
diff --git a/lib/cocoa/src/transport/THTTPSessionTransport.h b/lib/cocoa/src/transport/THTTPSessionTransport.h
deleted file mode 100644
index 003499b..0000000
--- a/lib/cocoa/src/transport/THTTPSessionTransport.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TAsyncTransport.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-typedef NSError *__nullable (^THTTPSessionTransportResponseValidateBlock) (NSHTTPURLResponse *response, NSData *responseData);
-
-
-@interface THTTPSessionTransportFactory : NSObject<TAsyncTransportFactory>
-
-@property (strong, nonatomic) THTTPSessionTransportResponseValidateBlock responseValidate;
-
-+(void) setupDefaultsForSessionConfiguration:(NSURLSessionConfiguration *)config
- withProtocolName:(NSString *)protocolName;
-
--(id) initWithSession:(NSURLSession *)session
- URL:(NSURL *)aURL;
-
-@end
-
-
-@interface THTTPSessionTransport : NSObject <TAsyncTransport>
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/transport/THTTPSessionTransport.m b/lib/cocoa/src/transport/THTTPSessionTransport.m
deleted file mode 100644
index c10b7fc..0000000
--- a/lib/cocoa/src/transport/THTTPSessionTransport.m
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * 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.
- */
-
-#import "THTTPSessionTransport.h"
-#import "TTransportError.h"
-
-
-@interface THTTPSessionTransportFactory ()
-
-@property (strong, nonatomic) NSURLSession *session;
-@property (strong, nonatomic) NSURL *url;
-
-@end
-
-
-@interface THTTPSessionTransport ()
-
-@property (strong, nonatomic) THTTPSessionTransportFactory *factory;
-@property (strong, nonatomic) NSMutableData *requestData;
-@property (strong, nonatomic) NSData *responseData;
-@property (assign, nonatomic) NSUInteger responseDataOffset;
-
--(instancetype) initWithFactory:(THTTPSessionTransportFactory *)factory;
-
-@end
-
-
-@implementation THTTPSessionTransportFactory
-
-+(void) setupDefaultsForSessionConfiguration:(NSURLSessionConfiguration *)config withProtocolName:(NSString *)protocolName
-{
- NSString *thriftContentType = @"application/x-thrift";
- if (protocolName.length) {
- thriftContentType = [thriftContentType stringByAppendingFormat:@"; p=%@", protocolName];
- }
-
- config.requestCachePolicy = NSURLRequestReloadIgnoringCacheData;
- config.HTTPShouldUsePipelining = YES;
- config.HTTPShouldSetCookies = NO;
- config.URLCache = nil;
- config.HTTPAdditionalHeaders = @{@"Content-Type":thriftContentType,
- @"Accept":thriftContentType,
- @"User-Agent":@"Thrift/Cocoa (Session)"};
-}
-
-
--(id) initWithSession:(NSURLSession *)session URL:(NSURL *)url
-{
- self = [super init];
- if (self) {
- _session = session;
- _url = url;
- }
-
- return self;
-}
-
--(id<TAsyncTransport>) newTransport
-{
- return [[THTTPSessionTransport alloc] initWithFactory:self];
-}
-
--(NSURLSessionDataTask *) taskWithRequest:(NSURLRequest *)request
- completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler
- error:(NSError *__autoreleasing *)error
-{
- NSURLSessionDataTask *newTask = [_session dataTaskWithRequest:request completionHandler:completionHandler];
- if (!newTask) {
- if (error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorUnknown
- userInfo:@{NSLocalizedDescriptionKey:@"Failed to create session data task"}];
- }
- return nil;
- }
-
- return newTask;
-}
-
--(NSError *) validateResponse:(NSHTTPURLResponse *)response data:(NSData *)data
-{
- if (_responseValidate) {
- return _responseValidate(response, data);
- }
- return nil;
-}
-
-@end
-
-
-
-@implementation THTTPSessionTransport
-
--(instancetype) initWithFactory:(THTTPSessionTransportFactory *)factory
-{
- self = [super init];
- if (self) {
- _factory = factory;
- }
- return self;
-}
-
--(BOOL) readAll:(UInt8 *)outBuffer offset:(UInt32)outBufferOffset length:(UInt32)length error:(NSError *__autoreleasing *)error
-{
- UInt32 got = [self readAvail:outBuffer offset:outBufferOffset maxLength:length error:error];
- if (got != length) {
-
- // Report underflow only if readAvail didn't report error already
- if (error && !*error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorEndOfFile
- userInfo:nil];
- }
-
- return NO;
- }
-
- return YES;
-}
-
--(UInt32) readAvail:(UInt8 *)outBuffer offset:(UInt32)outBufferOffset maxLength:(UInt32)maxLength error:(NSError *__autoreleasing *)error
-{
- NSUInteger avail = _responseData.length - _responseDataOffset;
-
- NSRange range;
- range.location = _responseDataOffset;
- range.length = MIN(maxLength, avail);
-
- [_responseData getBytes:outBuffer+outBufferOffset range:range];
- _responseDataOffset += range.length;
-
- return (UInt32)range.length;
-}
-
--(BOOL) write:(const UInt8 *)data offset:(UInt32)offset length:(UInt32)length error:(NSError *__autoreleasing *)error
-{
- if (!_requestData) {
- _requestData = [NSMutableData dataWithCapacity:256];
- }
-
- [_requestData appendBytes:data+offset length:length];
-
- return YES;
-}
-
--(void) flushWithCompletion:(TAsyncCompletionBlock)completed failure:(TAsyncFailureBlock)failure
-{
- NSError *error;
-
- NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:_factory.url];
- request.HTTPMethod = @"POST";
- request.HTTPBody = _requestData;
-
- _requestData = nil;
-
- NSURLSessionDataTask *task = [_factory taskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
-
- // Check response type
- if (!error && ![response isKindOfClass:NSHTTPURLResponse.class]) {
-
- error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorUnknown
- userInfo:@{TTransportErrorHttpErrorKey: @(THttpTransportErrorInvalidResponse)}];
-
- }
-
- // Check status code
- NSHTTPURLResponse *httpResponse = (id)response;
- if (!error && httpResponse.statusCode != 200) {
-
- THttpTransportError code;
- if (httpResponse.statusCode == 401) {
- code = THttpTransportErrorAuthentication;
- }
- else {
- code = THttpTransportErrorInvalidStatus;
- }
-
- error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorUnknown
- userInfo:@{TTransportErrorHttpErrorKey: @(code),
- @"statusCode":@(httpResponse.statusCode)}];
- }
-
- // Allow factory to check
- if (!error) {
- error = [_factory validateResponse:httpResponse data:data];
- }
-
- _responseDataOffset = 0;
-
- if (error) {
-
- _responseData = nil;
-
- failure(error);
-
- }
- else {
-
- if (data == nil) {
- data = [NSData data];
- }
-
- _responseData = data;
-
- completed(self);
- }
-
- } error:&error];
-
- if (!task) {
- failure(error);
- return;
- }
-
- [task resume];
-}
-
--(BOOL) flush:(NSError *__autoreleasing *)error
-{
- dispatch_semaphore_t completed = dispatch_semaphore_create(0);
-
- __block BOOL result;
- __block NSError *internalError;
-
- [self flushWithCompletion:^(id < TAsyncTransport > transport) {
-
- result = YES;
-
- dispatch_semaphore_signal(completed);
-
- } failure:^(NSError *error) {
-
- internalError = error;
-
- result = NO;
-
- dispatch_semaphore_signal(completed);
-
- }];
-
- dispatch_semaphore_wait(completed, DISPATCH_TIME_FOREVER);
-
- if (error) {
- *error = internalError;
- }
-
- return result;
-}
-
-@end
diff --git a/lib/cocoa/src/transport/THTTPTransport.h b/lib/cocoa/src/transport/THTTPTransport.h
deleted file mode 100644
index 3c35daf..0000000
--- a/lib/cocoa/src/transport/THTTPTransport.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TTransport.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@interface THTTPTransport : NSObject <TTransport>
-
--(id) initWithURL:(NSURL *)aURL;
-
--(id) initWithURL:(NSURL *)aURL
- userAgent:(nullable NSString *)userAgent
- timeout:(int)timeout;
-
--(void) setURL:(NSURL *)aURL;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/transport/THTTPTransport.m b/lib/cocoa/src/transport/THTTPTransport.m
deleted file mode 100644
index e4046c6..0000000
--- a/lib/cocoa/src/transport/THTTPTransport.m
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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.
- */
-
-#import "THTTPTransport.h"
-#import "TTransportError.h"
-
-
-@interface THTTPTransport ()
-
-@property (strong, nonatomic) NSURL *url;
-@property (strong, nonatomic) NSMutableURLRequest *request;
-@property (strong, nonatomic) NSMutableData *requestData;
-@property (strong, nonatomic) NSData *responseData;
-@property (assign, nonatomic) NSUInteger responseDataOffset;
-@property (strong, nonatomic) NSString *userAgent;
-@property (assign, nonatomic) NSTimeInterval timeout;
-
-@end
-
-
-@implementation THTTPTransport
-
--(void) setupRequest
-{
- // set up our request object that we'll use for each request
- _request = [[NSMutableURLRequest alloc] initWithURL:_url];
- [_request setHTTPMethod:@"POST"];
- [_request setValue:@"application/x-thrift" forHTTPHeaderField:@"Content-Type"];
- [_request setValue:@"application/x-thrift" forHTTPHeaderField:@"Accept"];
-
- NSString *userAgent = _userAgent;
- if (!userAgent) {
- userAgent = @"Thrift/Cocoa";
- }
- [_request setValue:userAgent forHTTPHeaderField:@"User-Agent"];
-
- [_request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
- if (_timeout) {
- [_request setTimeoutInterval:_timeout];
- }
-}
-
-
--(id) initWithURL:(NSURL *)aURL
-{
- return [self initWithURL:aURL
- userAgent:nil
- timeout:0];
-}
-
-
--(id) initWithURL:(NSURL *)aURL
- userAgent:(NSString *)aUserAgent
- timeout:(int)aTimeout
-{
- self = [super init];
- if (!self) {
- return nil;
- }
-
- _timeout = aTimeout;
- _userAgent = aUserAgent;
- _url = aURL;
-
- [self setupRequest];
-
- // create our request data buffer
- _requestData = [[NSMutableData alloc] initWithCapacity:1024];
-
- return self;
-}
-
--(void) setURL:(NSURL *)aURL
-{
- _url = aURL;
-
- [self setupRequest];
-}
-
--(BOOL) readAll:(UInt8 *)outBuffer offset:(UInt32)outBufferOffset length:(UInt32)length error:(NSError *__autoreleasing *)error
-{
- UInt32 got = [self readAvail:outBuffer offset:outBufferOffset maxLength:length error:error];
- if (got != length) {
-
- // Report underflow only if readAvail didn't report error already
- if (error && !*error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorEndOfFile
- userInfo:nil];
- }
-
- return NO;
- }
-
- return YES;
-}
-
--(UInt32) readAvail:(UInt8 *)outBuffer offset:(UInt32)outBufferOffset maxLength:(UInt32)maxLength error:(NSError *__autoreleasing *)error
-{
- NSUInteger avail = _responseData.length - _responseDataOffset;
-
- NSRange range;
- range.location = _responseDataOffset;
- range.length = MIN(maxLength, avail);
-
- [_responseData getBytes:outBuffer+outBufferOffset range:range];
- _responseDataOffset += range.length;
-
- return (UInt32)range.length;
-}
-
--(BOOL) write:(const UInt8 *)data offset:(UInt32)offset length:(UInt32)length error:(NSError *__autoreleasing *)error
-{
- [_requestData appendBytes:data+offset length:length];
-
- return YES;
-}
-
--(BOOL) flush:(NSError *__autoreleasing *)error
-{
- [_request setHTTPBody:_requestData];
-
- _responseDataOffset = 0;
-
- // make the HTTP request
- NSURLResponse *response;
- _responseData = [NSURLConnection sendSynchronousRequest:_request returningResponse:&response error:error];
- if (!_responseData) {
- return NO;
- }
-
- [_requestData setLength:0];
-
- if (![response isKindOfClass:NSHTTPURLResponse.class]) {
- if (error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorUnknown
- userInfo:@{TTransportErrorHttpErrorKey: @(THttpTransportErrorInvalidResponse)}];
- }
- return NO;
- }
-
- NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
- if ([httpResponse statusCode] != 200) {
- if (error) {
-
- THttpTransportError code;
- if (httpResponse.statusCode == 401) {
- code = THttpTransportErrorAuthentication;
- }
- else {
- code = THttpTransportErrorInvalidStatus;
- }
-
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorUnknown
- userInfo:@{TTransportErrorHttpErrorKey: @(code),
- @"statusCode":@(httpResponse.statusCode)}];
- }
- return NO;
- }
-
- return YES;
-}
-
-@end
diff --git a/lib/cocoa/src/transport/TMemoryBuffer.h b/lib/cocoa/src/transport/TMemoryBuffer.h
deleted file mode 100644
index 6249d32..0000000
--- a/lib/cocoa/src/transport/TMemoryBuffer.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TTransport.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@interface TMemoryBuffer : NSObject <TTransport>
-
--(NSData *) buffer;
-
--(id) initWithData:(NSData *)data;
-
--(id) initWithDataNoCopy:(NSMutableData *)data;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/transport/TMemoryBuffer.m b/lib/cocoa/src/transport/TMemoryBuffer.m
deleted file mode 100644
index ec19cc8..0000000
--- a/lib/cocoa/src/transport/TMemoryBuffer.m
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-#import "TMemoryBuffer.h"
-#import "TTransportError.h"
-
-
-#define GARBAGE_BUFFER_SIZE 4096 // 4KiB
-
-
-@interface TMemoryBuffer ()
-
-@property(strong, nonatomic) NSMutableData *buffer;
-@property(assign, nonatomic) UInt32 bufferOffset;
-
-@end
-
-
-@implementation TMemoryBuffer
-
--(id) init
-{
- if ((self = [super init])) {
- _buffer = [NSMutableData new];
- _bufferOffset = 0;
- }
- return self;
-}
-
--(id) initWithData:(NSData *)data
-{
- if (self = [super init]) {
- _buffer = [data mutableCopy];
- _bufferOffset = 0;
- }
- return self;
-}
-
--(id) initWithDataNoCopy:(NSMutableData *)data
-{
- if (self = [super init]) {
- _buffer = data;
- _bufferOffset = 0;
- }
- return self;
-}
-
--(BOOL) readAll:(UInt8 *)outBuffer offset:(UInt32)outBufferOffset length:(UInt32)length error:(NSError *__autoreleasing *)error
-{
- UInt32 got = [self readAvail:outBuffer offset:outBufferOffset maxLength:length error:error];
- if (got != length) {
-
- // Report underflow only if readAvail didn't report error already
- if (error && !*error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorEndOfFile
- userInfo:nil];
- }
-
- return NO;
- }
-
- return YES;
-}
-
--(UInt32) readAvail:(UInt8 *)outBuffer offset:(UInt32)outBufferOffset maxLength:(UInt32)maxLength error:(NSError *__autoreleasing *)error
-{
- UInt32 avail = (UInt32)_buffer.length - _bufferOffset;
- if (avail == 0) {
- return 0;
- }
-
- NSRange range;
- range.location = _bufferOffset;
- range.length = MIN(maxLength, avail);
-
- [_buffer getBytes:outBuffer + outBufferOffset range:range];
- _bufferOffset += range.length;
-
- if (_bufferOffset >= GARBAGE_BUFFER_SIZE) {
- [_buffer replaceBytesInRange:NSMakeRange(0, _bufferOffset) withBytes:NULL length:0];
- _bufferOffset = 0;
- }
-
- return (UInt32)range.length;
-}
-
--(BOOL) write:(const UInt8 *)inBuffer offset:(UInt32)inBufferOffset length:(UInt32)length error:(NSError *__autoreleasing *)error
-{
- [_buffer appendBytes:inBuffer + inBufferOffset length:length];
-
- return YES;
-}
-
--(NSData *) buffer
-{
- return _buffer;
-}
-
--(BOOL) flush:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-@end
diff --git a/lib/cocoa/src/transport/TNSFileHandleTransport.h b/lib/cocoa/src/transport/TNSFileHandleTransport.h
deleted file mode 100644
index db6edf3..0000000
--- a/lib/cocoa/src/transport/TNSFileHandleTransport.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.
- */
-
-
-#import <Foundation/Foundation.h>
-#import "TTransport.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@interface TNSFileHandleTransport : NSObject <TTransport>
-
--(id) initWithFileHandle:(NSFileHandle *)fileHandle;
-
--(id) initWithInputFileHandle:(NSFileHandle *)inputFileHandle
- outputFileHandle:(NSFileHandle *)outputFileHandle;
-
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/transport/TNSFileHandleTransport.m b/lib/cocoa/src/transport/TNSFileHandleTransport.m
deleted file mode 100644
index c907f87..0000000
--- a/lib/cocoa/src/transport/TNSFileHandleTransport.m
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.
- */
-
-
-#import "TNSFileHandleTransport.h"
-#import "TTransportError.h"
-
-
-@interface TNSFileHandleTransport ()
-
-@property(strong, nonatomic) NSFileHandle *inputFileHandle;
-@property(strong, nonatomic) NSFileHandle *outputFileHandle;
-
-@end
-
-
-@implementation TNSFileHandleTransport
-
--(id) initWithFileHandle:(NSFileHandle *)fileHandle
-{
- return [self initWithInputFileHandle:fileHandle
- outputFileHandle:fileHandle];
-}
-
-
--(id) initWithInputFileHandle:(NSFileHandle *)aInputFileHandle
- outputFileHandle:(NSFileHandle *)aOutputFileHandle
-{
- self = [super init];
- if (self) {
- _inputFileHandle = aInputFileHandle;
- _outputFileHandle = aOutputFileHandle;
- }
- return self;
-}
-
-
--(BOOL) readAll:(UInt8 *)buf offset:(UInt32)off length:(UInt32)len error:(NSError *__autoreleasing *)error
-{
- UInt32 got = 0;
- while (got < len) {
-
- NSData *d = [_inputFileHandle readDataOfLength:len-got];
- if (d.length == 0) {
- if (error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorEndOfFile
- userInfo:nil];
- }
- return NO;
- }
-
- [d getBytes:buf+got length:d.length];
- got += d.length;
- }
- return YES;
-}
-
-
--(UInt32) readAvail:(UInt8 *)buf offset:(UInt32)off maxLength:(UInt32)len error:(NSError *__autoreleasing *)error
-{
- UInt32 got = 0;
- while (got < len) {
-
- NSData *d = [_inputFileHandle readDataOfLength:len-got];
- if (d.length == 0) {
- break;
- }
-
- [d getBytes:buf+got length:d.length];
- got += d.length;
- }
- return got;
-}
-
-
--(BOOL) write:(const UInt8 *)data offset:(UInt32)offset length:(UInt32)length error:(NSError *__autoreleasing *)error
-{
- void *pos = (void *)data + offset;
-
- @try {
- [_outputFileHandle writeData:[NSData dataWithBytesNoCopy:pos length:length freeWhenDone:NO]];
- }
- @catch (NSException *e) {
- if (error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorNotOpen
- userInfo:@{}];
- }
- return NO;
- }
-
- return YES;
-}
-
-
--(BOOL) flush:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
-@end
diff --git a/lib/cocoa/src/transport/TNSStreamTransport.h b/lib/cocoa/src/transport/TNSStreamTransport.h
deleted file mode 100644
index 54c4884..0000000
--- a/lib/cocoa/src/transport/TNSStreamTransport.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TTransport.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@interface TNSStreamTransport : NSObject <TTransport>
-
-@property (strong, nonatomic) NSInputStream *input;
-@property (strong, nonatomic) NSOutputStream *output;
-
--(id) initWithInputStream:(nullable NSInputStream *)input
- outputStream:(nullable NSOutputStream *)output;
-
--(id) initWithInputStream:(NSInputStream *)input;
-
--(id) initWithOutputStream:(NSOutputStream *)output;
-
--(void) close;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/transport/TNSStreamTransport.m b/lib/cocoa/src/transport/TNSStreamTransport.m
deleted file mode 100644
index 18c41d3..0000000
--- a/lib/cocoa/src/transport/TNSStreamTransport.m
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.
- */
-
-#import "TNSStreamTransport.h"
-#import "TTransportError.h"
-
-
-@interface TNSStreamTransport ()
-@end
-
-
-@implementation TNSStreamTransport
-
--(id) initWithInputStream:(NSInputStream *)input
- outputStream:(NSOutputStream *)output
-{
- self = [super init];
- if (self) {
- _input = input;
- _output = output;
- }
- return self;
-}
-
--(id) initWithInputStream:(NSInputStream *)input
-{
- return [self initWithInputStream:input outputStream:nil];
-}
-
--(id) initWithOutputStream:(NSOutputStream *)output
-{
- return [self initWithInputStream:nil outputStream:output];
-}
-
--(void) dealloc
-{
- [self close];
-}
-
--(BOOL) readAll:(UInt8 *)buf offset:(UInt32)off length:(UInt32)len error:(NSError *__autoreleasing *)error
-{
- UInt32 got = 0;
- while (got < len) {
-
- UInt32 read = (UInt32)[_input read:buf+off+got maxLength:len-got];
- if (read <= 0) {
- if (error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorNotOpen
- userInfo:@{}];
- }
- return NO;
- }
-
- got += read;
- }
-
- return YES;
-}
-
-
--(UInt32) readAvail:(UInt8 *)buf offset:(UInt32)off maxLength:(UInt32)len error:(NSError *__autoreleasing *)error
-{
- UInt32 got = 0;
- while (got < len) {
-
- UInt32 read = (UInt32)[_input read:buf+off+got maxLength:len-got];
- if (read <= 0) {
- break;
- }
-
- got += read;
- }
-
- return got;
-}
-
-
--(BOOL) write:(const UInt8 *)data offset:(UInt32)offset length:(UInt32)length error:(NSError *__autoreleasing *)error
-{
- UInt32 got = 0;
- NSInteger total = 0;
- while (got < length) {
-
- total = [_output write:data+offset+got maxLength:length-got];
- if (total == -1) {
- if (error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorNotOpen
- userInfo:@{}];
- }
- return NO;
- }
- else if (total == 0) {
- if (error) {
- *error = [NSError errorWithDomain:TTransportErrorDomain
- code:TTransportErrorEndOfFile
- userInfo:@{}];
- }
- return NO;
- }
-
- got += total;
- }
-
- return YES;
-}
-
--(BOOL) flush:(NSError *__autoreleasing *)error
-{
- return YES;
-}
-
--(void) close
-{
- NSInputStream *input = self.input;
- if (input) {
- // Close and reset inputstream
- CFReadStreamSetProperty((__bridge CFReadStreamRef)(input), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
- [input setDelegate:nil];
- [input close];
- [input removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- input = nil;
- }
-
- NSOutputStream *output = self.output;
- if (output) {
- // Close and reset outputstream
- CFWriteStreamSetProperty((__bridge CFWriteStreamRef)(output), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
- [output setDelegate:nil];
- [output close];
- [output removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- output = nil;
- }
-}
-
-@end
diff --git a/lib/cocoa/src/transport/TSSLSocketTransport.h b/lib/cocoa/src/transport/TSSLSocketTransport.h
deleted file mode 100644
index b606c4a..0000000
--- a/lib/cocoa/src/transport/TSSLSocketTransport.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TNSStreamTransport.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@interface TSSLSocketTransport : TNSStreamTransport <NSStreamDelegate>
-
--(id) initWithHostname:(NSString *)hostname
- port:(int)port
- error:(NSError **)error;
-
--(BOOL) isOpen;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/transport/TSSLSocketTransport.m b/lib/cocoa/src/transport/TSSLSocketTransport.m
deleted file mode 100644
index 1b1214f..0000000
--- a/lib/cocoa/src/transport/TSSLSocketTransport.m
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * 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.
- */
-#import <Foundation/Foundation.h>
-#import <CoreFoundation/CoreFoundation.h>
-#import "TSSLSocketTransport.h"
-#import "TSSLSocketTransportError.h"
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-
-#if !TARGET_OS_IPHONE
-#import <CoreServices/CoreServices.h>
-#else
-#import <CFNetwork/CFNetwork.h>
-#endif
-
-@interface TSSLSocketTransport ()
-
-@property(strong, nonatomic) NSString *sslHostname;
-@property(assign, nonatomic) int sd;
-
-@end
-
-
-@implementation TSSLSocketTransport
-
--(id) initWithHostname:(NSString *)hostname
- port:(int)port
- error:(NSError **)error
-{
- _sslHostname = hostname;
- CFReadStreamRef readStream = NULL;
- CFWriteStreamRef writeStream = NULL;
-
-
- /* create a socket structure */
- struct sockaddr_in pin;
- struct hostent *hp = NULL;
- for (int i = 0; i < 10; i++) {
-
-
-
- if ((hp = gethostbyname([hostname UTF8String])) == NULL) {
- NSLog(@"failed to resolve hostname %@", hostname);
- herror("resolv");
- if (i == 9) {
- if (error) {
- *error = [NSError errorWithDomain:TSSLSocketTransportErrorDomain
- code:TSSLSocketTransportErrorHostanameResolution
- userInfo:nil];
- }
- return nil;
- }
- [NSThread sleepForTimeInterval:0.2];
- }
- else {
- break;
- }
- }
-
- memset(&pin, 0, sizeof(pin));
- pin.sin_family = AF_INET;
- memcpy(&pin.sin_addr, hp->h_addr, sizeof(struct in_addr));
- pin.sin_port = htons(port);
-
- /* create the socket */
- if ((_sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
- NSLog(@"failed to create socket for host %@:%d", hostname, port);
- if (error) {
- *error = [NSError errorWithDomain:TSSLSocketTransportErrorDomain
- code:TSSLSocketTransportErrorSocketCreate
- userInfo:nil];
- }
- return nil;
- }
-
- /* open a connection */
- if (connect(_sd, (struct sockaddr *)&pin, sizeof(pin)) == -1) {
- NSLog(@"failed to create conenct to host %@:%d", hostname, port);
- if (error) {
- *error = [NSError errorWithDomain:TSSLSocketTransportErrorDomain
- code:TSSLSocketTransportErrorConnect
- userInfo:nil];
- }
- return nil;
- }
- CFStreamCreatePairWithSocket(kCFAllocatorDefault, _sd, &readStream, &writeStream);
-
- CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
- CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
-
- NSInputStream *inputStream;
- NSOutputStream *outputStream;
-
- if (readStream && writeStream) {
-
- CFReadStreamSetProperty(readStream,
- kCFStreamPropertySocketSecurityLevel,
- kCFStreamSocketSecurityLevelTLSv1);
-
- NSDictionary *settings = @{(__bridge NSString *)kCFStreamSSLValidatesCertificateChain: @YES};
-
- CFReadStreamSetProperty((CFReadStreamRef)readStream,
- kCFStreamPropertySSLSettings,
- (CFTypeRef)settings);
-
- CFWriteStreamSetProperty((CFWriteStreamRef)writeStream,
- kCFStreamPropertySSLSettings,
- (CFTypeRef)settings);
-
- inputStream = (__bridge NSInputStream *)readStream;
- [inputStream setDelegate:self];
- [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- [inputStream open];
-
- outputStream = (__bridge NSOutputStream *)writeStream;
- [outputStream setDelegate:self];
- [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- [outputStream open];
-
- CFRelease(readStream);
- CFRelease(writeStream);
- }
-
- self = [super initWithInputStream:inputStream outputStream:outputStream];
-
- return self;
-}
-
--(void) dealloc
-{
- [self close];
-}
-
-#pragma mark -
-#pragma mark NSStreamDelegate
-
--(void) stream:(NSStream *)aStream
- handleEvent:(NSStreamEvent)eventCode
-{
- switch (eventCode) {
- case NSStreamEventNone:
- break;
-
- case NSStreamEventHasBytesAvailable:
- break;
-
- case NSStreamEventOpenCompleted:
- break;
-
- case NSStreamEventHasSpaceAvailable: {
-
- BOOL proceed = NO;
- SecTrustResultType trustResult = kSecTrustResultInvalid;
- CFMutableArrayRef newPolicies = NULL;
-
- do {
-
- SecTrustRef trust = (__bridge SecTrustRef)[aStream propertyForKey:(NSString *)kCFStreamPropertySSLPeerTrust];
-
- // Add new policy to current list of policies
- SecPolicyRef policy = SecPolicyCreateSSL(NO, (__bridge CFStringRef)(_sslHostname));
- if (!policy) {
- break;
- }
-
- CFArrayRef policies;
- if (SecTrustCopyPolicies(trust, &policies) != errSecSuccess) {
- CFRelease(policy);
- break;
- }
-
- newPolicies = CFArrayCreateMutableCopy(NULL, 0, policies);
- CFArrayAppendValue(newPolicies, policy);
-
- CFRelease(policies);
- CFRelease(policy);
-
- // Update trust policies
- if (SecTrustSetPolicies(trust, newPolicies) != errSecSuccess) {
- break;
- }
-
- // Evaluate the trust chain
- if (SecTrustEvaluate(trust, &trustResult) != errSecSuccess) {
- break;
- }
-
- switch (trustResult) {
- case kSecTrustResultProceed:
- // NSLog(@"Trusted by USER");
- proceed = YES;
- break;
-
- case kSecTrustResultUnspecified:
- // NSLog(@"Trusted by OS");
- proceed = YES;
- break;
-
- case kSecTrustResultRecoverableTrustFailure:
- proceed = recoverFromTrustFailure(trust, trustResult);
- break;
-
- case kSecTrustResultDeny:
- // NSLog(@"Deny");
- break;
-
- case kSecTrustResultFatalTrustFailure:
- // NSLog(@"FatalTrustFailure");
- break;
-
- case kSecTrustResultOtherError:
- // NSLog(@"OtherError");
- break;
-
- case kSecTrustResultInvalid:
- // NSLog(@"Invalid");
- break;
-
- default:
- // NSLog(@"Default");
- break;
- }
-
- }
- while (NO);
-
- if (!proceed) {
- NSLog(@"TSSLSocketTransport: Cannot trust certificate. Result: %u", trustResult);
- [aStream close];
- }
-
- if (newPolicies) {
- CFRelease(newPolicies);
- }
-
- }
- break;
-
- case NSStreamEventErrorOccurred: {
- NSLog(@"TSSLSocketTransport: Error occurred opening stream: %@", [aStream streamError]);
- break;
- }
-
- case NSStreamEventEndEncountered:
- break;
- }
-}
-
-BOOL recoverFromTrustFailure(SecTrustRef myTrust, SecTrustResultType lastTrustResult)
-{
- CFAbsoluteTime trustTime = SecTrustGetVerifyTime(myTrust);
- CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
-
- CFAbsoluteTime timeIncrement = 31536000;
- CFAbsoluteTime newTime = currentTime - timeIncrement;
-
- if (trustTime - newTime) {
-
- CFDateRef newDate = CFDateCreate(NULL, newTime);
- SecTrustSetVerifyDate(myTrust, newDate);
- CFRelease(newDate);
-
- if (SecTrustEvaluate(myTrust, &lastTrustResult) != errSecSuccess) {
- return NO;
- }
-
- }
-
- if (lastTrustResult == kSecTrustResultProceed || lastTrustResult == kSecTrustResultUnspecified) {
- return YES;
- }
-
- NSLog(@"TSSLSocketTransport: Unable to recover certificate trust failure");
- return YES;
-}
-
--(BOOL) isOpen
-{
- if (_sd > 0) {
- return TRUE;
- }
- else {
- return FALSE;
- }
-}
-
-@end
diff --git a/lib/cocoa/src/transport/TSSLSocketTransportError.h b/lib/cocoa/src/transport/TSSLSocketTransportError.h
deleted file mode 100644
index e17f39e..0000000
--- a/lib/cocoa/src/transport/TSSLSocketTransportError.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-#import "TTransportError.h"
-
-
-extern NSString *TSSLSocketTransportErrorDomain;
-
-
-typedef NS_ENUM (int, TSSLSocketTransportError) {
- TSSLSocketTransportErrorHostanameResolution = -10000,
- TSSLSocketTransportErrorSocketCreate = -10001,
- TSSLSocketTransportErrorConnect = -10002,
-};
diff --git a/lib/cocoa/src/transport/TSSLSocketTransportError.m b/lib/cocoa/src/transport/TSSLSocketTransportError.m
deleted file mode 100644
index bcf941c..0000000
--- a/lib/cocoa/src/transport/TSSLSocketTransportError.m
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.
- */
-
-#import "TSSLSocketTransportError.h"
-
-
-NSString *TSSLSocketTransportErrorDomain = @"TSSLSocketTransportErrorDomain";
diff --git a/lib/cocoa/src/transport/TSocketTransport.h b/lib/cocoa/src/transport/TSocketTransport.h
deleted file mode 100644
index a7b91a2..0000000
--- a/lib/cocoa/src/transport/TSocketTransport.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "TNSStreamTransport.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@interface TSocketTransport : TNSStreamTransport
-
--(id) initWithHostname:(NSString *)hostname
- port:(int)port;
-
--(id) initWithPath:(NSString *)path;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/transport/TSocketTransport.m b/lib/cocoa/src/transport/TSocketTransport.m
deleted file mode 100644
index 9c58abb..0000000
--- a/lib/cocoa/src/transport/TSocketTransport.m
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.
- */
-#import "TSocketTransport.h"
-
-#if !TARGET_OS_IPHONE
-#import <CoreServices/CoreServices.h>
-#else
-#import <CFNetwork/CFNetwork.h>
-#endif
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <sys/un.h>
-
-@interface TSocketTransport () <NSStreamDelegate>
-@end
-
-
-@implementation TSocketTransport
-
-- (id) initWithReadStream: (CFReadStreamRef) readStream writeStream: (CFWriteStreamRef) writeStream
-{
- NSInputStream *inputStream = nil;
- NSOutputStream *outputStream = nil;
-
- if (readStream && writeStream) {
-
- CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
- CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
-
- inputStream = (__bridge NSInputStream *)readStream;
- [inputStream setDelegate:self];
- [inputStream scheduleInRunLoop:NSRunLoop.currentRunLoop forMode:NSDefaultRunLoopMode];
- [inputStream open];
-
- outputStream = (__bridge NSOutputStream *)writeStream;
- [outputStream setDelegate:self];
- [outputStream scheduleInRunLoop:NSRunLoop.currentRunLoop forMode:NSDefaultRunLoopMode];
- [outputStream open];
- }
- else {
-
- if (readStream) {
- CFRelease(readStream);
- }
-
- if (writeStream) {
- CFRelease(writeStream);
- }
-
- return nil;
- }
-
- return [super initWithInputStream:inputStream outputStream:outputStream];
-}
-
-- (id) initWithHostname: (NSString *) hostname
- port: (int) port
-{
- CFReadStreamRef readStream = NULL;
- CFWriteStreamRef writeStream = NULL;
- CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)hostname, port, &readStream, &writeStream);
- return [self initWithReadStream:readStream writeStream:writeStream];
-}
-
-- (id) initWithPath: (NSString *) path
-{
- CFSocketNativeHandle sockfd = socket(AF_LOCAL, SOCK_STREAM, IPPROTO_IP);
- int yes = 1;
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
- {
- NSLog(@"TSocketTransport: Unable to set REUSEADDR property of socket.");
- return nil;
- }
-
- NSData *serverAddress = [[self class] createAddressWithPath:path];
-
- CFReadStreamRef readStream = NULL;
- CFWriteStreamRef writeStream = NULL;
- CFStreamCreatePairWithSocket(kCFAllocatorDefault, sockfd, &readStream, &writeStream);
- if (!readStream || !writeStream)
- {
- NSLog(@"TSocketTransport: Unable to create read/write stream pair for socket.");
- return nil;
- }
-
- if (connect(sockfd, (struct sockaddr *)serverAddress.bytes, (socklen_t) serverAddress.length) < 0)
- {
- NSLog(@"TSocketTransport: Connect error: %s\n", strerror(errno));
- return nil;
- }
-
- return [self initWithReadStream:readStream writeStream:writeStream];
-}
-
-+ (NSData *) createAddressWithPath: (NSString *)path
-{
- struct sockaddr_un servaddr;
-
- size_t nullTerminatedPathLength = path.length + 1;
- if (nullTerminatedPathLength> sizeof(servaddr.sun_path)) {
- NSLog(@"TSocketTransport: Unable to create socket at path %@. Path is too long.", path);
- return nil;
- }
-
- bzero(&servaddr,sizeof(servaddr));
- servaddr.sun_family = AF_LOCAL;
- memcpy(servaddr.sun_path, path.UTF8String, nullTerminatedPathLength);
- servaddr.sun_len = SUN_LEN(&servaddr);
-
- return [NSData dataWithBytes:&servaddr length:sizeof(servaddr)];
-}
-
-
-@end
diff --git a/lib/cocoa/src/transport/TTransport.h b/lib/cocoa/src/transport/TTransport.h
deleted file mode 100644
index 558cf60..0000000
--- a/lib/cocoa/src/transport/TTransport.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.
- */
-
-#import <Foundation/Foundation.h>
-
-
-NS_ASSUME_NONNULL_BEGIN
-
-
-@protocol TTransport <NSObject>
-
-/**
- * Guarantees that all of len bytes are read
- *
- * @param buf Buffer to read into
- * @param off Index in buffer to start storing bytes at
- * @param len Maximum number of bytes to read
- * @return YES if succeeded, NO if failed
- * @throws TTransportError if there was an error reading data
- */
--(BOOL) readAll:(UInt8 *)buf offset:(UInt32)off length:(UInt32)len error:(NSError *__autoreleasing *)error;
-
--(UInt32) readAvail:(UInt8 *)buf offset:(UInt32)off maxLength:(UInt32)maxLen error:(NSError *__autoreleasing *)error;
-
--(BOOL) write:(const UInt8 *)data offset:(UInt32)offset length:(UInt32)length error:(NSError *__autoreleasing *)error;
-
--(BOOL) flush:(NSError *__autoreleasing *)error;
-
-@end
-
-
-NS_ASSUME_NONNULL_END
diff --git a/lib/cocoa/src/transport/TTransportError.h b/lib/cocoa/src/transport/TTransportError.h
deleted file mode 100644
index c8c9f06..0000000
--- a/lib/cocoa/src/transport/TTransportError.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- */
-
-#import "TError.h"
-
-
-extern NSString *TTransportErrorDomain;
-
-
-typedef NS_ENUM (int, TTransportError) {
- TTransportErrorUnknown = 0,
- TTransportErrorNotOpen = 1,
- TTransportErrorAlreadyOpen = 2,
- TTransportErrorTimedOut = 3,
- TTransportErrorEndOfFile = 4,
-};
-
-
-extern NSString *TTransportErrorExtendedErrorKey;
-extern NSString *TTransportErrorHttpErrorKey;
-
-
-typedef NS_ENUM(int, THttpTransportError) {
- THttpTransportErrorInvalidResponse = 1001,
- THttpTransportErrorInvalidStatus = 1002,
- THttpTransportErrorAuthentication = 1003,
-};
diff --git a/lib/cocoa/src/transport/TTransportError.m b/lib/cocoa/src/transport/TTransportError.m
deleted file mode 100644
index b1af076..0000000
--- a/lib/cocoa/src/transport/TTransportError.m
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.
- */
-
-#import "TTransportError.h"
-
-
-NSString *TTransportErrorDomain = @"TTransportErrorDomain";
-
-
-NSString *TTransportErrorExtendedErrorKey = @"extendedError";
-NSString *TTransportErrorHttpErrorKey = @"httpError";
diff --git a/lib/cpp/CMakeLists.txt b/lib/cpp/CMakeLists.txt
index 1ed0bfa..e92da60 100755
--- a/lib/cpp/CMakeLists.txt
+++ b/lib/cpp/CMakeLists.txt
@@ -17,9 +17,16 @@
# under the License.
#
-include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
+# Remove the following once lib/cpp no longer depends on boost headers:
+include(BoostMacros)
+REQUIRE_BOOST_HEADERS()
+
include_directories(src)
+if(NOT BUILD_SHARED_LIBS)
+ add_definitions("-DTHRIFT_STATIC_DEFINE")
+endif()
+
# SYSLIBS contains libraries that need to be linked to all lib targets
set(SYSLIBS "")
@@ -33,7 +40,6 @@
src/thrift/async/TConcurrentClientSyncInfo.cpp
src/thrift/concurrency/ThreadManager.cpp
src/thrift/concurrency/TimerManager.cpp
- src/thrift/concurrency/Util.cpp
src/thrift/processor/PeekProcessor.cpp
src/thrift/protocol/TBase64Utils.cpp
src/thrift/protocol/TDebugProtocol.cpp
@@ -91,8 +97,7 @@
)
endif()
-# If OpenSSL is not found just ignore the OpenSSL stuff
-find_package(OpenSSL)
+# If OpenSSL is not found or disabled just ignore the OpenSSL stuff
if(OPENSSL_FOUND AND WITH_OPENSSL)
list( APPEND thriftcpp_SOURCES
src/thrift/transport/TSSLSocket.cpp
@@ -102,39 +107,19 @@
list(APPEND SYSLIBS "${OPENSSL_LIBRARIES}")
endif()
-# WITH_*THREADS selects which threading library to use
-if(WITH_BOOSTTHREADS)
- set( thriftcpp_threads_SOURCES
- src/thrift/concurrency/BoostThreadFactory.cpp
- src/thrift/concurrency/BoostMonitor.cpp
- src/thrift/concurrency/BoostMutex.cpp
- )
- list(APPEND SYSLIBS "${Boost_LIBRARIES}")
-elseif(UNIX AND NOT WITH_STDTHREADS)
+if(UNIX)
if(ANDROID)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
else()
list(APPEND SYSLIBS pthread)
endif()
- set( thriftcpp_threads_SOURCES
- src/thrift/concurrency/PosixThreadFactory.cpp
- src/thrift/concurrency/Mutex.cpp
- src/thrift/concurrency/Monitor.cpp
- )
-else()
- if(UNIX)
- if(ANDROID)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
- else()
- list(APPEND SYSLIBS pthread)
- endif()
- endif()
- set( thriftcpp_threads_SOURCES
- src/thrift/concurrency/StdThreadFactory.cpp
- src/thrift/concurrency/StdMutex.cpp
- src/thrift/concurrency/StdMonitor.cpp
- )
endif()
+set( thriftcpp_threads_SOURCES
+ src/thrift/concurrency/ThreadFactory.cpp
+ src/thrift/concurrency/Thread.cpp
+ src/thrift/concurrency/Monitor.cpp
+ src/thrift/concurrency/Mutex.cpp
+)
# Thrift non blocking server
set( thriftcppnb_SOURCES
@@ -145,7 +130,7 @@
src/thrift/async/TEvhttpClientChannel.cpp
)
-# Thrift zlib server
+# Thrift zlib transport
set( thriftcppz_SOURCES
src/thrift/transport/TZlibTransport.cpp
src/thrift/protocol/THeaderProtocol.cpp
@@ -154,12 +139,6 @@
src/thrift/transport/THeaderTransport.cpp
)
-# Thrift Qt4 server
-set( thriftcppqt_SOURCES
- src/thrift/qt/TQIODeviceTransport.cpp
- src/thrift/qt/TQTcpServer.cpp
-)
-
# Contains the thrift specific ADD_LIBRARY_THRIFT and TARGET_LINK_LIBRARIES_THRIFT
include(ThriftMacros)
@@ -169,14 +148,16 @@
else()
TARGET_LINK_LIBRARIES_THRIFT(thrift ${SYSLIBS})
endif()
+ADD_PKGCONFIG_THRIFT(thrift)
if(WITH_LIBEVENT)
find_package(Libevent REQUIRED) # Libevent comes with CMake support form upstream
include_directories(SYSTEM ${LIBEVENT_INCLUDE_DIRS})
ADD_LIBRARY_THRIFT(thriftnb ${thriftcppnb_SOURCES})
+ LINK_AGAINST_THRIFT_LIBRARY(thriftnb thrift)
TARGET_LINK_LIBRARIES_THRIFT(thriftnb ${SYSLIBS} ${LIBEVENT_LIBRARIES})
- TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY(thriftnb thrift)
+ ADD_PKGCONFIG_THRIFT(thrift-nb)
endif()
if(WITH_ZLIB)
@@ -186,27 +167,18 @@
ADD_LIBRARY_THRIFT(thriftz ${thriftcppz_SOURCES})
TARGET_LINK_LIBRARIES_THRIFT(thriftz ${SYSLIBS} ${ZLIB_LIBRARIES})
TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY(thriftz thrift)
-endif()
-
-if(WITH_QT4)
- set(CMAKE_AUTOMOC ON)
- find_package(Qt4 REQUIRED COMPONENTS QtCore QtNetwork)
- ADD_LIBRARY_THRIFT(thriftqt ${thriftcppqt_SOURCES})
- TARGET_LINK_LIBRARIES_THRIFT(thriftqt ${SYSLIBS} Qt4::QtCore Qt4::QtNetwork)
- TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY(thriftqt thrift)
+ ADD_PKGCONFIG_THRIFT(thrift-z)
endif()
if(WITH_QT5)
- # Qt5 has its own directory to avoid conflict with Qt4 caused by CMAKE_AUTOMOC
add_subdirectory(src/thrift/qt)
+ ADD_PKGCONFIG_THRIFT(thrift-qt5)
endif()
if(MSVC)
add_definitions("-DUNICODE -D_UNICODE")
endif()
-add_definitions("-D__STDC_LIMIT_MACROS")
-
# Install the headers
install(DIRECTORY "src/thrift" DESTINATION "${INCLUDE_INSTALL_DIR}"
FILES_MATCHING PATTERN "*.h" PATTERN "*.tcc")
diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am
index 83ccd9b..114ff17 100755
--- a/lib/cpp/Makefile.am
+++ b/lib/cpp/Makefile.am
@@ -19,21 +19,14 @@
AUTOMAKE_OPTIONS = subdir-objects
-moc_%.cpp: %.h
- $(QT_MOC) $(QT_CFLAGS) $< -o $@
-
moc__%.cpp: %.h
$(QT5_MOC) $(QT5_CFLAGS) $< -o $@
SUBDIRS = .
if WITH_TESTS
-# This file is needed by compiler with plugin, while test/Makefile.am needs compiler
-# So test directory is directly picked by top level Makefile.am for plugin build
-if !WITH_PLUGIN
SUBDIRS += test
endif
-endif
pkgconfigdir = $(libdir)/pkgconfig
@@ -52,10 +45,6 @@
lib_LTLIBRARIES += libthriftz.la
pkgconfig_DATA += thrift-z.pc
endif
-if AMX_HAVE_QT
-lib_LTLIBRARIES += libthriftqt.la
-pkgconfig_DATA += thrift-qt.pc
-endif
if AMX_HAVE_QT5
lib_LTLIBRARIES += libthriftqt5.la
pkgconfig_DATA += thrift-qt5.pc
@@ -74,7 +63,6 @@
src/thrift/async/TConcurrentClientSyncInfo.cpp \
src/thrift/concurrency/ThreadManager.cpp \
src/thrift/concurrency/TimerManager.cpp \
- src/thrift/concurrency/Util.cpp \
src/thrift/processor/PeekProcessor.cpp \
src/thrift/protocol/TDebugProtocol.cpp \
src/thrift/protocol/TJSONProtocol.cpp \
@@ -106,15 +94,10 @@
src/thrift/server/TThreadPoolServer.cpp \
src/thrift/server/TThreadedServer.cpp
-if WITH_BOOSTTHREADS
-libthrift_la_SOURCES += src/thrift/concurrency/BoostThreadFactory.cpp \
- src/thrift/concurrency/BoostMonitor.cpp \
- src/thrift/concurrency/BoostMutex.cpp
-else
libthrift_la_SOURCES += src/thrift/concurrency/Mutex.cpp \
- src/thrift/concurrency/Monitor.cpp \
- src/thrift/concurrency/PosixThreadFactory.cpp
-endif
+ src/thrift/concurrency/ThreadFactory.cpp \
+ src/thrift/concurrency/Thread.cpp \
+ src/thrift/concurrency/Monitor.cpp
libthriftnb_la_SOURCES = src/thrift/server/TNonblockingServer.cpp \
src/thrift/async/TEvhttpServer.cpp \
@@ -125,39 +108,31 @@
src/thrift/protocol/THeaderProtocol.cpp
-libthriftqt_la_MOC = src/thrift/qt/moc_TQTcpServer.cpp
-nodist_libthriftqt_la_SOURCES = $(libthriftqt_la_MOC)
-libthriftqt_la_SOURCES = src/thrift/qt/TQIODeviceTransport.cpp \
- src/thrift/qt/TQTcpServer.cpp
-CLEANFILES = $(libthriftqt_la_MOC)
-
libthriftqt5_la_MOC = src/thrift/qt/moc__TQTcpServer.cpp
nodist_libthriftqt5_la_SOURCES = $(libthriftqt5_la_MOC)
libthriftqt5_la_SOURCES = src/thrift/qt/TQIODeviceTransport.cpp \
src/thrift/qt/TQTcpServer.cpp
-CLEANFILES += $(libthriftqt5_la_MOC)
+CLEANFILES = $(libthriftqt5_la_MOC)
# Flags for the various libraries
libthriftnb_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBEVENT_CPPFLAGS)
libthriftz_la_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CPPFLAGS)
-libthriftqt_la_CPPFLAGS = $(AM_CPPFLAGS) $(QT_CFLAGS)
libthriftqt5_la_CPPFLAGS = $(AM_CPPFLAGS) $(QT5_CFLAGS)
if QT5_REDUCE_RELOCATIONS
libthriftqt5_la_CPPFLAGS += -fPIC
endif
libthriftnb_la_CXXFLAGS = $(AM_CXXFLAGS)
libthriftz_la_CXXFLAGS = $(AM_CXXFLAGS)
-libthriftqt_la_CXXFLAGS = $(AM_CXXFLAGS)
libthriftqt5_la_CXXFLAGS = $(AM_CXXFLAGS)
libthriftnb_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS)
libthriftz_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(ZLIB_LIBS)
-libthriftqt_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(QT_LIBS)
libthriftqt5_la_LDFLAGS = -release $(VERSION) $(BOOST_LDFLAGS) $(QT5_LIBS)
include_thriftdir = $(includedir)/thrift
include_thrift_HEADERS = \
$(top_builddir)/config.h \
src/thrift/thrift-config.h \
+ src/thrift/thrift_export.h \
src/thrift/TDispatchProcessor.h \
src/thrift/Thrift.h \
src/thrift/TOutput.h \
@@ -165,26 +140,18 @@
src/thrift/TApplicationException.h \
src/thrift/TLogging.h \
src/thrift/TToString.h \
- src/thrift/stdcxx.h \
src/thrift/TBase.h
include_concurrencydir = $(include_thriftdir)/concurrency
include_concurrency_HEADERS = \
- src/thrift/concurrency/BoostThreadFactory.h \
src/thrift/concurrency/Exception.h \
src/thrift/concurrency/Mutex.h \
src/thrift/concurrency/Monitor.h \
- src/thrift/concurrency/PlatformThreadFactory.h \
- src/thrift/concurrency/PosixThreadFactory.h \
- src/thrift/concurrency/StdMonitor.cpp \
- src/thrift/concurrency/StdMutex.cpp \
- src/thrift/concurrency/StdThreadFactory.cpp \
- src/thrift/concurrency/StdThreadFactory.h \
+ src/thrift/concurrency/ThreadFactory.h \
src/thrift/concurrency/Thread.h \
src/thrift/concurrency/ThreadManager.h \
src/thrift/concurrency/TimerManager.h \
- src/thrift/concurrency/FunctionRunner.h \
- src/thrift/concurrency/Util.h
+ src/thrift/concurrency/FunctionRunner.h
include_protocoldir = $(include_thriftdir)/protocol
include_protocol_HEADERS = \
@@ -281,7 +248,6 @@
thrift-nb.pc.in \
thrift.pc.in \
thrift-z.pc.in \
- thrift-qt.pc.in \
thrift-qt5.pc.in \
src/thrift/qt/CMakeLists.txt \
$(WINDOWS_DIST)
diff --git a/lib/cpp/README.md b/lib/cpp/README.md
index e744a6a..8a897d1 100755
--- a/lib/cpp/README.md
+++ b/lib/cpp/README.md
@@ -33,8 +33,8 @@
Thrift is divided into two libraries.
-* libthrift - The core Thrift library contains all the core Thrift code. It requires
- boost shared pointers, pthreads, and librt.
+* libthrift - The core Thrift library contains all the core Thrift code. This requires
+ openssl, pthreads, and librt.
* libthriftnb - This library contains the Thrift nonblocking server, which uses libevent.
To link this library you will also need to link libevent.
@@ -54,14 +54,12 @@
## Dependencies
-If your C++ environment implements C++11 or later, thrift will automatically use
-std::shared_ptr. Otherwise you will need the boost library to provide a shared_ptr
-implementation for C++ environments pre-C++11. If you are linking against code
-that expects to be using boost::shared_ptr, you can define the preprocessor
-variable FORCE_BOOST_SMART_PTR for your build of thrift to make it use boost instead
-of std for a number of memory related classes. See thrift/stdcxx.h for more.
+C++11 is required at a minimum. C++03/C++98 are not supported after version 0.12.0.
-libevent (for libthriftnb only)
+Boost is required to run the C++ unit tests. It is not necessary to link against
+the runtime library.
+
+libevent (for libthriftnb only) - most linux distributions have dev packages for this:
http://monkey.org/~provos/libevent/
# Using Thrift with C++ on Windows
@@ -85,42 +83,20 @@
## Linking Against Thrift
You need to link your project that uses thrift against all the thrift
-dependencies; in the case of libthrift, boost and for
+dependencies; in the case of libthrift, openssl, pthreads, and librt and for
libthriftnb, libevent.
In the project properties you must also set HAVE_CONFIG_H as force include
-the config header: "windows/confg.h"
+the config header: "windows/config.h"
## Dependencies
-The same dependencies for shared_ptr as described above apply to windows as well.
-
-boost thread
-http://www.boost.org/doc/libs/release/doc/html/thread.html
-
libevent (for libthriftnb only)
http://monkey.org/~provos/libevent/
-## Notes on boost thread (static vs shared):
-
-By default lib/cpp/windows/force_inc.h defines:
-
- #define BOOST_ALL_NO_LIB 1
- #define BOOST_THREAD_NO_LIB 1
-
-This has for effect to have the host application linking against Thrift
-to have to link with boost thread as a static library.
-
-If you wanted instead to link with boost thread as a shared library,
-you'll need to uncomment those two lines, and recompile.
-
## Windows version compatibility
-The Thrift library targets Windows XP for broadest compatbility. A notable
-difference is in the Windows-specific implementation of the socket poll
-function. To target Vista, Win7 or other versions, comment out the line
-
- #define TARGET_WIN_XP.
+The Thrift library targets Windows 7 or latter versions. The supports for windows XP and Vista are avaiable until 0.12.0.
## Named Pipes
@@ -138,50 +114,16 @@
## Implementation
-There're two main classes TSSLSocketFactory and TSSLSocket. Instances of
+There are two main classes TSSLSocketFactory and TSSLSocket. Instances of
TSSLSocket are always created from TSSLSocketFactory.
-PosixSSLThreadFactory creates PosixSSLThread. The only difference from the
-PthreadThread type is that it cleanups OpenSSL error queue upon exiting
-the thread. Ideally, OpenSSL APIs should only be called from PosixSSLThread.
-
## How to use SSL APIs
-This is for demo. In real code, typically only one TSSLSocketFactory
-instance is needed.
+See the TestClient.cpp and TestServer.cpp files for examples.
- shared_ptr<TSSLSocketFactory> getSSLSocketFactory() {
- shared_ptr<TSSLSocketFactory> factory(new TSSLSocketFactory());
- // client: load trusted certificates
- factory->loadTrustedCertificates("my-trusted-ca-certificates.pem");
- // client: optionally set your own access manager, otherwise,
- // the default client access manager will be loaded.
+### AccessManager (certificate validation)
- factory->loadCertificate("my-certificate-signed-by-ca.pem");
- factory->loadPrivateKey("my-private-key.pem");
- // server: optionally setup access manager
- // shared_ptr<AccessManager> accessManager(new MyAccessManager);
- // factory->access(accessManager);
- ...
- }
-
-
-client code sample
-
- shared_ptr<TSSLSocketFactory> factory = getSSLSocketFactory();
- shared_ptr<TSocket> socket = factory.createSocket(host, port);
- shared_ptr<TBufferedTransport> transport(new TBufferedTransport(socket));
- ...
-
-
-server code sample
-
- shared_ptr<TSSLSocketFactory> factory = getSSLSocketFactory();
- shared_ptr<TSSLServerSocket> socket(new TSSLServerSocket(port, factory));
- shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory));
- ...
-
-## AccessManager
+An example of certificate validation can be found in TestServer.cpp.
AccessManager defines a callback interface. It has three callback methods:
@@ -272,8 +214,48 @@
The PRNG seed is key to the application security. This method should be
overridden if it's not strong enough for you.
+# Deprecations
+
+## 0.12.0
+
+Support for C++03/C++98 was deprecated.
+Support for Boost at runtime was deprecated.
+
# Breaking Changes
+## 1.0.0
+
+THRIFT-4720:
+The classes Monitor and TimerManager now use std::chrono::milliseconds for timeout, the methods and functions involving THRIFT_TIMESPEC and timeval have been removed, the related tests have been modified.
+
+Support for Windows XP/Vista has been dropped.
+
+Support for C++03/C++98 has been dropped. Use version 0.12.0 to support that
+language level. As a consequence, boost is no longer required as a runtime
+library depenedency, but is is still required to build the runtime library
+and to run the unit tests. We will work towards removing boost as a
+build dependency for folks who just want to build the runtime and not
+run the tests. This means the header thrift/stdcxx.h has been removed and
+anything that relied on it has been changed to directly use C++11 concepts.
+
+THRIFT-4730:
+The classes BoostThreadFactory, PosixThreadFactory, StdThreadFactory, and
+PlatformThreadFactory have been removed, and we will use a ThreadFactory
+based on C++11 (essentially StdThreadFactory was renamed ThreadFactory).
+
+THRIFT-4732:
+The CMake build options WITH_SHARED_LIBS and WITH_STATIC_LIBS are deprecated.
+The project no longer performs a side-by-side static and shared build; you
+tell CMake through BUILD_SHARED_LIBS whether to make shared or static
+libraries now. This is CMake standard behavior.
+
+THRIFT-4735:
+Qt4 support was removed.
+
+THRIFT-4762:
+Added `const` specifier to `TTransport::getOrigin()`. This changes its function signature.
+It's recommended to add the `override` specifier in implementations derived from `TTransport`.
+
## 0.11.0
Older versions of thrift depended on the <boost/smart_ptr.hpp> classes which
diff --git a/lib/cpp/src/thrift/TApplicationException.h b/lib/cpp/src/thrift/TApplicationException.h
index 81d9424..cd1b3e7 100644
--- a/lib/cpp/src/thrift/TApplicationException.h
+++ b/lib/cpp/src/thrift/TApplicationException.h
@@ -57,7 +57,7 @@
TApplicationException(TApplicationExceptionType type, const std::string& message)
: TException(message), type_(type) {}
- virtual ~TApplicationException() throw() {}
+ ~TApplicationException() noexcept override = default;
/**
* Returns an error code that provides information about the type of error
@@ -67,7 +67,7 @@
*/
TApplicationExceptionType getType() const { return type_; }
- virtual const char* what() const throw() {
+ const char* what() const noexcept override {
if (message_.empty()) {
switch (type_) {
case UNKNOWN:
diff --git a/lib/cpp/src/thrift/TBase.h b/lib/cpp/src/thrift/TBase.h
index a274bcd..e2e78e7 100644
--- a/lib/cpp/src/thrift/TBase.h
+++ b/lib/cpp/src/thrift/TBase.h
@@ -28,7 +28,7 @@
class TBase {
public:
- virtual ~TBase(){};
+ virtual ~TBase() = default;
virtual uint32_t read(protocol::TProtocol* iprot) = 0;
virtual uint32_t write(protocol::TProtocol* oprot) const = 0;
};
diff --git a/lib/cpp/src/thrift/TDispatchProcessor.h b/lib/cpp/src/thrift/TDispatchProcessor.h
index dadc87b..ae522b2 100644
--- a/lib/cpp/src/thrift/TDispatchProcessor.h
+++ b/lib/cpp/src/thrift/TDispatchProcessor.h
@@ -33,15 +33,15 @@
template <class Protocol_>
class TDispatchProcessorT : public TProcessor {
public:
- virtual bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
- stdcxx::shared_ptr<protocol::TProtocol> out,
- void* connectionContext) {
+ bool process(std::shared_ptr<protocol::TProtocol> in,
+ std::shared_ptr<protocol::TProtocol> out,
+ void* connectionContext) override {
protocol::TProtocol* inRaw = in.get();
protocol::TProtocol* outRaw = out.get();
// Try to dynamic cast to the template protocol type
- Protocol_* specificIn = dynamic_cast<Protocol_*>(inRaw);
- Protocol_* specificOut = dynamic_cast<Protocol_*>(outRaw);
+ auto* specificIn = dynamic_cast<Protocol_*>(inRaw);
+ auto* specificOut = dynamic_cast<Protocol_*>(outRaw);
if (specificIn && specificOut) {
return processFast(specificIn, specificOut, connectionContext);
}
@@ -105,9 +105,9 @@
*/
class TDispatchProcessor : public TProcessor {
public:
- virtual bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
- stdcxx::shared_ptr<protocol::TProtocol> out,
- void* connectionContext) {
+ bool process(std::shared_ptr<protocol::TProtocol> in,
+ std::shared_ptr<protocol::TProtocol> out,
+ void* connectionContext) override {
std::string fname;
protocol::TMessageType mtype;
int32_t seqid;
diff --git a/lib/cpp/src/thrift/TOutput.cpp b/lib/cpp/src/thrift/TOutput.cpp
index ae3a9e2..8d163a9 100644
--- a/lib/cpp/src/thrift/TOutput.cpp
+++ b/lib/cpp/src/thrift/TOutput.cpp
@@ -27,7 +27,9 @@
namespace apache {
namespace thrift {
-TOutput GlobalOutput;
+THRIFT_EXPORT TOutput GlobalOutput;
+
+TOutput::TOutput() : f_(&errorTimeWrapper) {}
void TOutput::printf(const char* message, ...) {
#ifndef THRIFT_SQUELCH_CONSOLE_OUTPUT
@@ -60,7 +62,7 @@
#endif
char* heap_buf = (char*)malloc((need + 1) * sizeof(char));
- if (heap_buf == NULL) {
+ if (heap_buf == nullptr) {
#ifdef _MSC_VER
va_start(ap, message);
vsnprintf_s(stack_buf, STACK_BUF_SIZE, _TRUNCATE, message, ap);
diff --git a/lib/cpp/src/thrift/TOutput.h b/lib/cpp/src/thrift/TOutput.h
index 1375f73..26c9a56 100644
--- a/lib/cpp/src/thrift/TOutput.h
+++ b/lib/cpp/src/thrift/TOutput.h
@@ -20,12 +20,14 @@
#ifndef _THRIFT_OUTPUT_H_
#define _THRIFT_OUTPUT_H_ 1
+#include <thrift/thrift_export.h>
+
namespace apache {
namespace thrift {
class TOutput {
public:
- TOutput() : f_(&errorTimeWrapper) {}
+ TOutput();
inline void setOutputFunction(void (*function)(const char*)) { f_ = function; }
@@ -51,7 +53,7 @@
void (*f_)(const char*);
};
-extern TOutput GlobalOutput;
+THRIFT_EXPORT extern TOutput GlobalOutput;
}
} // namespace apache::thrift
diff --git a/lib/cpp/src/thrift/TProcessor.h b/lib/cpp/src/thrift/TProcessor.h
index 27294d3..65bf3d4 100644
--- a/lib/cpp/src/thrift/TProcessor.h
+++ b/lib/cpp/src/thrift/TProcessor.h
@@ -22,7 +22,6 @@
#include <string>
#include <thrift/protocol/TProtocol.h>
-#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@@ -36,7 +35,7 @@
*/
class TProcessorEventHandler {
public:
- virtual ~TProcessorEventHandler() {}
+ virtual ~TProcessorEventHandler() = default;
/**
* Called before calling other callback methods.
@@ -47,7 +46,7 @@
virtual void* getContext(const char* fn_name, void* serverContext) {
(void)fn_name;
(void)serverContext;
- return NULL;
+ return nullptr;
}
/**
@@ -109,7 +108,7 @@
}
protected:
- TProcessorEventHandler() {}
+ TProcessorEventHandler() = default;
};
/**
@@ -120,10 +119,10 @@
TProcessorContextFreer(TProcessorEventHandler* handler, void* context, const char* method)
: handler_(handler), context_(context), method_(method) {}
~TProcessorContextFreer() {
- if (handler_ != NULL)
+ if (handler_ != nullptr)
handler_->freeContext(context_, method_);
}
- void unregister() { handler_ = NULL; }
+ void unregister() { handler_ = nullptr; }
private:
apache::thrift::TProcessorEventHandler* handler_;
@@ -140,30 +139,30 @@
*/
class TProcessor {
public:
- virtual ~TProcessor() {}
+ virtual ~TProcessor() = default;
- virtual bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
- stdcxx::shared_ptr<protocol::TProtocol> out,
+ virtual bool process(std::shared_ptr<protocol::TProtocol> in,
+ std::shared_ptr<protocol::TProtocol> out,
void* connectionContext) = 0;
- bool process(stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> io, void* connectionContext) {
+ bool process(std::shared_ptr<apache::thrift::protocol::TProtocol> io, void* connectionContext) {
return process(io, io, connectionContext);
}
- stdcxx::shared_ptr<TProcessorEventHandler> getEventHandler() const { return eventHandler_; }
+ std::shared_ptr<TProcessorEventHandler> getEventHandler() const { return eventHandler_; }
- void setEventHandler(stdcxx::shared_ptr<TProcessorEventHandler> eventHandler) {
+ void setEventHandler(std::shared_ptr<TProcessorEventHandler> eventHandler) {
eventHandler_ = eventHandler;
}
protected:
- TProcessor() {}
+ TProcessor() = default;
- stdcxx::shared_ptr<TProcessorEventHandler> eventHandler_;
+ std::shared_ptr<TProcessorEventHandler> eventHandler_;
};
/**
- * This is a helper class to allow stdcxx::shared_ptr to be used with handler
+ * This is a helper class to allow std::shared_ptr to be used with handler
* pointers returned by the generated handler factories.
*
* The handler factory classes generated by the thrift compiler return raw
@@ -177,7 +176,7 @@
template <typename HandlerFactory_>
class ReleaseHandler {
public:
- ReleaseHandler(const stdcxx::shared_ptr<HandlerFactory_>& handlerFactory)
+ ReleaseHandler(const std::shared_ptr<HandlerFactory_>& handlerFactory)
: handlerFactory_(handlerFactory) {}
void operator()(typename HandlerFactory_::Handler* handler) {
@@ -187,23 +186,23 @@
}
private:
- stdcxx::shared_ptr<HandlerFactory_> handlerFactory_;
+ std::shared_ptr<HandlerFactory_> handlerFactory_;
};
struct TConnectionInfo {
// The input and output protocols
- stdcxx::shared_ptr<protocol::TProtocol> input;
- stdcxx::shared_ptr<protocol::TProtocol> output;
+ std::shared_ptr<protocol::TProtocol> input;
+ std::shared_ptr<protocol::TProtocol> output;
// The underlying transport used for the connection
// This is the transport that was returned by TServerTransport::accept(),
// and it may be different than the transport pointed to by the input and
// output protocols.
- stdcxx::shared_ptr<transport::TTransport> transport;
+ std::shared_ptr<transport::TTransport> transport;
};
class TProcessorFactory {
public:
- virtual ~TProcessorFactory() {}
+ virtual ~TProcessorFactory() = default;
/**
* Get the TProcessor to use for a particular connection.
@@ -212,17 +211,17 @@
* accepted on. This generally means that this call does not need to be
* thread safe, as it will always be invoked from a single thread.
*/
- virtual stdcxx::shared_ptr<TProcessor> getProcessor(const TConnectionInfo& connInfo) = 0;
+ virtual std::shared_ptr<TProcessor> getProcessor(const TConnectionInfo& connInfo) = 0;
};
class TSingletonProcessorFactory : public TProcessorFactory {
public:
- TSingletonProcessorFactory(stdcxx::shared_ptr<TProcessor> processor) : processor_(processor) {}
+ TSingletonProcessorFactory(std::shared_ptr<TProcessor> processor) : processor_(processor) {}
- stdcxx::shared_ptr<TProcessor> getProcessor(const TConnectionInfo&) { return processor_; }
+ std::shared_ptr<TProcessor> getProcessor(const TConnectionInfo&) override { return processor_; }
private:
- stdcxx::shared_ptr<TProcessor> processor_;
+ std::shared_ptr<TProcessor> processor_;
};
}
} // apache::thrift
diff --git a/lib/cpp/src/thrift/Thrift.h b/lib/cpp/src/thrift/Thrift.h
index e8e70eb..6cb24e6 100644
--- a/lib/cpp/src/thrift/Thrift.h
+++ b/lib/cpp/src/thrift/Thrift.h
@@ -42,9 +42,6 @@
#include <exception>
#include <typeinfo>
-#include <boost/utility/enable_if.hpp>
-#include <boost/type_traits/is_convertible.hpp>
-
#include <thrift/TLogging.h>
#include <thrift/TOutput.h>
@@ -82,9 +79,9 @@
TException(const std::string& message) : message_(message) {}
- virtual ~TException() throw() {}
+ ~TException() noexcept override = default;
- virtual const char* what() const throw() {
+ const char* what() const noexcept override {
if (message_.empty()) {
return "Default TException.";
} else {
@@ -101,14 +98,14 @@
template <class E>
static TDelayedException* delayException(const E& e);
virtual void throw_it() = 0;
- virtual ~TDelayedException(){};
+ virtual ~TDelayedException() = default;
};
template <class E>
class TExceptionWrapper : public TDelayedException {
public:
TExceptionWrapper(const E& e) : e_(e) {}
- virtual void throw_it() {
+ void throw_it() override {
E temp(e_);
delete this;
throw temp;
diff --git a/lib/cpp/src/thrift/async/TAsyncBufferProcessor.h b/lib/cpp/src/thrift/async/TAsyncBufferProcessor.h
index 0d56c78..e3c3597 100644
--- a/lib/cpp/src/thrift/async/TAsyncBufferProcessor.h
+++ b/lib/cpp/src/thrift/async/TAsyncBufferProcessor.h
@@ -20,7 +20,7 @@
#ifndef _THRIFT_TASYNC_BUFFER_PROCESSOR_H_
#define _THRIFT_TASYNC_BUFFER_PROCESSOR_H_ 1
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/transport/TBufferTransports.h>
namespace apache {
@@ -34,10 +34,10 @@
// forcefully close the connection (if applicable).
// "in" and "out" should be TMemoryBuffer or similar,
// not a wrapper around a socket.
- virtual void process(stdcxx::function<void(bool healthy)> _return,
- stdcxx::shared_ptr<transport::TBufferBase> ibuf,
- stdcxx::shared_ptr<transport::TBufferBase> obuf) = 0;
- virtual ~TAsyncBufferProcessor() {}
+ virtual void process(std::function<void(bool healthy)> _return,
+ std::shared_ptr<transport::TBufferBase> ibuf,
+ std::shared_ptr<transport::TBufferBase> obuf) = 0;
+ virtual ~TAsyncBufferProcessor() = default;
};
}
}
diff --git a/lib/cpp/src/thrift/async/TAsyncChannel.cpp b/lib/cpp/src/thrift/async/TAsyncChannel.cpp
index c87659f..01b9113 100644
--- a/lib/cpp/src/thrift/async/TAsyncChannel.cpp
+++ b/lib/cpp/src/thrift/async/TAsyncChannel.cpp
@@ -18,7 +18,6 @@
*/
#include <thrift/async/TAsyncChannel.h>
-#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@@ -27,8 +26,8 @@
void TAsyncChannel::sendAndRecvMessage(const VoidCallback& cob,
TMemoryBuffer* sendBuf,
TMemoryBuffer* recvBuf) {
- apache::thrift::stdcxx::function<void()> send_done
- = apache::thrift::stdcxx::bind(&TAsyncChannel::recvMessage, this, cob, recvBuf);
+ std::function<void()> send_done
+ = std::bind(&TAsyncChannel::recvMessage, this, cob, recvBuf);
sendMessage(send_done, sendBuf);
}
diff --git a/lib/cpp/src/thrift/async/TAsyncChannel.h b/lib/cpp/src/thrift/async/TAsyncChannel.h
index f8d2b03..22cf383 100644
--- a/lib/cpp/src/thrift/async/TAsyncChannel.h
+++ b/lib/cpp/src/thrift/async/TAsyncChannel.h
@@ -20,7 +20,8 @@
#ifndef _THRIFT_ASYNC_TASYNCCHANNEL_H_
#define _THRIFT_ASYNC_TASYNCCHANNEL_H_ 1
-#include <thrift/stdcxx.h>
+#include <functional>
+#include <memory>
#include <thrift/Thrift.h>
namespace apache {
@@ -38,9 +39,9 @@
class TAsyncChannel {
public:
- typedef apache::thrift::stdcxx::function<void()> VoidCallback;
+ typedef std::function<void()> VoidCallback;
- virtual ~TAsyncChannel() {}
+ virtual ~TAsyncChannel() = default;
// is the channel in a good state?
virtual bool good() const = 0;
diff --git a/lib/cpp/src/thrift/async/TAsyncDispatchProcessor.h b/lib/cpp/src/thrift/async/TAsyncDispatchProcessor.h
index a1450f0..2a694ac 100644
--- a/lib/cpp/src/thrift/async/TAsyncDispatchProcessor.h
+++ b/lib/cpp/src/thrift/async/TAsyncDispatchProcessor.h
@@ -34,15 +34,15 @@
template <class Protocol_>
class TAsyncDispatchProcessorT : public TAsyncProcessor {
public:
- virtual void process(apache::thrift::stdcxx::function<void(bool success)> _return,
- stdcxx::shared_ptr<protocol::TProtocol> in,
- stdcxx::shared_ptr<protocol::TProtocol> out) {
+ void process(std::function<void(bool success)> _return,
+ std::shared_ptr<protocol::TProtocol> in,
+ std::shared_ptr<protocol::TProtocol> out) override {
protocol::TProtocol* inRaw = in.get();
protocol::TProtocol* outRaw = out.get();
// Try to dynamic cast to the template protocol type
- Protocol_* specificIn = dynamic_cast<Protocol_*>(inRaw);
- Protocol_* specificOut = dynamic_cast<Protocol_*>(outRaw);
+ auto* specificIn = dynamic_cast<Protocol_*>(inRaw);
+ auto* specificOut = dynamic_cast<Protocol_*>(outRaw);
if (specificIn && specificOut) {
return processFast(_return, specificIn, specificOut);
}
@@ -70,7 +70,7 @@
return this->dispatchCall(_return, inRaw, outRaw, fname, seqid);
}
- void processFast(apache::thrift::stdcxx::function<void(bool success)> _return,
+ void processFast(std::function<void(bool success)> _return,
Protocol_* in,
Protocol_* out) {
std::string fname;
@@ -87,13 +87,13 @@
return this->dispatchCallTemplated(_return, in, out, fname, seqid);
}
- virtual void dispatchCall(apache::thrift::stdcxx::function<void(bool ok)> _return,
+ virtual void dispatchCall(std::function<void(bool ok)> _return,
apache::thrift::protocol::TProtocol* in,
apache::thrift::protocol::TProtocol* out,
const std::string& fname,
int32_t seqid) = 0;
- virtual void dispatchCallTemplated(apache::thrift::stdcxx::function<void(bool ok)> _return,
+ virtual void dispatchCallTemplated(std::function<void(bool ok)> _return,
Protocol_* in,
Protocol_* out,
const std::string& fname,
@@ -106,9 +106,9 @@
*/
class TAsyncDispatchProcessor : public TAsyncProcessor {
public:
- virtual void process(apache::thrift::stdcxx::function<void(bool success)> _return,
- stdcxx::shared_ptr<protocol::TProtocol> in,
- stdcxx::shared_ptr<protocol::TProtocol> out) {
+ void process(std::function<void(bool success)> _return,
+ std::shared_ptr<protocol::TProtocol> in,
+ std::shared_ptr<protocol::TProtocol> out) override {
protocol::TProtocol* inRaw = in.get();
protocol::TProtocol* outRaw = out.get();
@@ -131,7 +131,7 @@
return dispatchCall(_return, inRaw, outRaw, fname, seqid);
}
- virtual void dispatchCall(apache::thrift::stdcxx::function<void(bool ok)> _return,
+ virtual void dispatchCall(std::function<void(bool ok)> _return,
apache::thrift::protocol::TProtocol* in,
apache::thrift::protocol::TProtocol* out,
const std::string& fname,
diff --git a/lib/cpp/src/thrift/async/TAsyncProcessor.h b/lib/cpp/src/thrift/async/TAsyncProcessor.h
index afc4ffa..0192339 100644
--- a/lib/cpp/src/thrift/async/TAsyncProcessor.h
+++ b/lib/cpp/src/thrift/async/TAsyncProcessor.h
@@ -21,7 +21,7 @@
#define _THRIFT_TASYNCPROCESSOR_H_ 1
#include <thrift/protocol/TProtocol.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/TProcessor.h>
namespace apache {
@@ -35,32 +35,32 @@
class TAsyncProcessor {
public:
- virtual ~TAsyncProcessor() {}
+ virtual ~TAsyncProcessor() = default;
- virtual void process(stdcxx::function<void(bool success)> _return,
- stdcxx::shared_ptr<protocol::TProtocol> in,
- stdcxx::shared_ptr<protocol::TProtocol> out) = 0;
+ virtual void process(std::function<void(bool success)> _return,
+ std::shared_ptr<protocol::TProtocol> in,
+ std::shared_ptr<protocol::TProtocol> out) = 0;
- void process(stdcxx::function<void(bool success)> _return,
- stdcxx::shared_ptr<protocol::TProtocol> io) {
+ void process(std::function<void(bool success)> _return,
+ std::shared_ptr<protocol::TProtocol> io) {
return process(_return, io, io);
}
- stdcxx::shared_ptr<TProcessorEventHandler> getEventHandler() const { return eventHandler_; }
+ std::shared_ptr<TProcessorEventHandler> getEventHandler() const { return eventHandler_; }
- void setEventHandler(stdcxx::shared_ptr<TProcessorEventHandler> eventHandler) {
+ void setEventHandler(std::shared_ptr<TProcessorEventHandler> eventHandler) {
eventHandler_ = eventHandler;
}
protected:
- TAsyncProcessor() {}
+ TAsyncProcessor() = default;
- stdcxx::shared_ptr<TProcessorEventHandler> eventHandler_;
+ std::shared_ptr<TProcessorEventHandler> eventHandler_;
};
class TAsyncProcessorFactory {
public:
- virtual ~TAsyncProcessorFactory() {}
+ virtual ~TAsyncProcessorFactory() = default;
/**
* Get the TAsyncProcessor to use for a particular connection.
@@ -69,7 +69,7 @@
* accepted on. This generally means that this call does not need to be
* thread safe, as it will always be invoked from a single thread.
*/
- virtual stdcxx::shared_ptr<TAsyncProcessor> getProcessor(const TConnectionInfo& connInfo) = 0;
+ virtual std::shared_ptr<TAsyncProcessor> getProcessor(const TConnectionInfo& connInfo) = 0;
};
}
}
diff --git a/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.cpp b/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.cpp
index b9ffb04..cb5201b 100644
--- a/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.cpp
+++ b/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.cpp
@@ -26,23 +26,23 @@
namespace thrift {
namespace async {
-void TAsyncProtocolProcessor::process(apache::thrift::stdcxx::function<void(bool healthy)> _return,
- stdcxx::shared_ptr<TBufferBase> ibuf,
- stdcxx::shared_ptr<TBufferBase> obuf) {
- stdcxx::shared_ptr<TProtocol> iprot(pfact_->getProtocol(ibuf));
- stdcxx::shared_ptr<TProtocol> oprot(pfact_->getProtocol(obuf));
+void TAsyncProtocolProcessor::process(std::function<void(bool healthy)> _return,
+ std::shared_ptr<TBufferBase> ibuf,
+ std::shared_ptr<TBufferBase> obuf) {
+ std::shared_ptr<TProtocol> iprot(pfact_->getProtocol(ibuf));
+ std::shared_ptr<TProtocol> oprot(pfact_->getProtocol(obuf));
return underlying_
- ->process(apache::thrift::stdcxx::bind(&TAsyncProtocolProcessor::finish,
+ ->process(std::bind(&TAsyncProtocolProcessor::finish,
_return,
oprot,
- apache::thrift::stdcxx::placeholders::_1),
+ std::placeholders::_1),
iprot,
oprot);
}
/* static */ void TAsyncProtocolProcessor::finish(
- apache::thrift::stdcxx::function<void(bool healthy)> _return,
- stdcxx::shared_ptr<TProtocol> oprot,
+ std::function<void(bool healthy)> _return,
+ std::shared_ptr<TProtocol> oprot,
bool healthy) {
(void)oprot;
// This is a stub function to hold a reference to oprot.
diff --git a/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.h b/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.h
index ce3883c..ace72b6 100644
--- a/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.h
+++ b/lib/cpp/src/thrift/async/TAsyncProtocolProcessor.h
@@ -30,23 +30,23 @@
class TAsyncProtocolProcessor : public TAsyncBufferProcessor {
public:
- TAsyncProtocolProcessor(stdcxx::shared_ptr<TAsyncProcessor> underlying,
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact)
+ TAsyncProtocolProcessor(std::shared_ptr<TAsyncProcessor> underlying,
+ std::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact)
: underlying_(underlying), pfact_(pfact) {}
- virtual void process(apache::thrift::stdcxx::function<void(bool healthy)> _return,
- stdcxx::shared_ptr<apache::thrift::transport::TBufferBase> ibuf,
- stdcxx::shared_ptr<apache::thrift::transport::TBufferBase> obuf);
+ void process(std::function<void(bool healthy)> _return,
+ std::shared_ptr<apache::thrift::transport::TBufferBase> ibuf,
+ std::shared_ptr<apache::thrift::transport::TBufferBase> obuf) override;
- virtual ~TAsyncProtocolProcessor() {}
+ ~TAsyncProtocolProcessor() override = default;
private:
- static void finish(apache::thrift::stdcxx::function<void(bool healthy)> _return,
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> oprot,
+ static void finish(std::function<void(bool healthy)> _return,
+ std::shared_ptr<apache::thrift::protocol::TProtocol> oprot,
bool healthy);
- stdcxx::shared_ptr<TAsyncProcessor> underlying_;
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
+ std::shared_ptr<TAsyncProcessor> underlying_;
+ std::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
};
}
}
diff --git a/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.cpp b/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.cpp
index c7e27c0..0dac524 100644
--- a/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.cpp
+++ b/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.cpp
@@ -17,10 +17,11 @@
* under the License.
*/
-#include <thrift/async/TConcurrentClientSyncInfo.h>
-#include <thrift/TApplicationException.h>
-#include <thrift/transport/TTransportException.h>
#include <limits>
+#include <memory>
+#include <thrift/TApplicationException.h>
+#include <thrift/async/TConcurrentClientSyncInfo.h>
+#include <thrift/transport/TTransportException.h>
namespace apache { namespace thrift { namespace async {
@@ -75,7 +76,7 @@
MonitorPtr monitor;
{
Guard seqidGuard(seqidMutex_);
- MonitorMap::iterator i = seqidToMonitorMap_.find(rseqid);
+ auto i = seqidToMonitorMap_.find(rseqid);
if(i == seqidToMonitorMap_.end())
throwBadSeqId_();
monitor = i->second;
@@ -140,15 +141,15 @@
{
wakeupSomeone_ = true;
stop_ = true;
- for(MonitorMap::iterator i = seqidToMonitorMap_.begin(); i != seqidToMonitorMap_.end(); ++i)
- i->second->notify();
+ for(auto & i : seqidToMonitorMap_)
+ i.second->notify();
}
TConcurrentClientSyncInfo::MonitorPtr
TConcurrentClientSyncInfo::newMonitor_(const Guard &)
{
if(freeMonitors_.empty())
- return MonitorPtr(new Monitor(&readMutex_));
+ return std::make_shared<Monitor>(&readMutex_);
MonitorPtr retval;
//swapping to avoid an atomic operation
retval.swap(freeMonitors_.back());
diff --git a/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h b/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h
index 9ec77b9..0bc5eb5 100644
--- a/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h
+++ b/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.h
@@ -22,7 +22,7 @@
#include <thrift/protocol/TProtocol.h>
#include <thrift/concurrency/Mutex.h>
#include <thrift/concurrency/Monitor.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <vector>
#include <string>
#include <map>
@@ -60,7 +60,7 @@
class TConcurrentClientSyncInfo {
private: // typedefs
- typedef stdcxx::shared_ptr< ::apache::thrift::concurrency::Monitor> MonitorPtr;
+ typedef std::shared_ptr< ::apache::thrift::concurrency::Monitor> MonitorPtr;
typedef std::map<int32_t, MonitorPtr> MonitorMap;
public:
diff --git a/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp b/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp
index 6af8104..7656596 100644
--- a/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp
+++ b/lib/cpp/src/thrift/async/TEvhttpClientChannel.cpp
@@ -41,15 +41,15 @@
struct event_base* eb,
struct evdns_base* dnsbase)
- : host_(host), path_(path), conn_(NULL) {
+ : host_(host), path_(path), conn_(nullptr) {
conn_ = evhttp_connection_base_new(eb, dnsbase, address, port);
- if (conn_ == NULL) {
+ if (conn_ == nullptr) {
throw TException("evhttp_connection_new failed");
}
}
TEvhttpClientChannel::~TEvhttpClientChannel() {
- if (conn_ != NULL) {
+ if (conn_ != nullptr) {
evhttp_connection_free(conn_);
}
}
@@ -58,7 +58,7 @@
apache::thrift::transport::TMemoryBuffer* sendBuf,
apache::thrift::transport::TMemoryBuffer* recvBuf) {
struct evhttp_request* req = evhttp_request_new(response, this);
- if (req == NULL) {
+ if (req == nullptr) {
throw TException("evhttp_request_new failed");
}
@@ -110,7 +110,7 @@
assert(!completionQueue_.empty());
Completion completion = completionQueue_.front();
completionQueue_.pop();
- if (req == NULL) {
+ if (req == nullptr) {
try {
completion.first();
} catch (const TTransportException& e) {
@@ -142,7 +142,7 @@
}
/* static */ void TEvhttpClientChannel::response(struct evhttp_request* req, void* arg) {
- TEvhttpClientChannel* self = (TEvhttpClientChannel*)arg;
+ auto* self = (TEvhttpClientChannel*)arg;
try {
self->finish(req);
} catch (std::exception& e) {
diff --git a/lib/cpp/src/thrift/async/TEvhttpClientChannel.h b/lib/cpp/src/thrift/async/TEvhttpClientChannel.h
index 3515ca2..f742726 100644
--- a/lib/cpp/src/thrift/async/TEvhttpClientChannel.h
+++ b/lib/cpp/src/thrift/async/TEvhttpClientChannel.h
@@ -23,7 +23,7 @@
#include <queue>
#include <string>
#include <utility>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/async/TAsyncChannel.h>
struct event_base;
@@ -52,24 +52,24 @@
const char* address,
int port,
struct event_base* eb,
- struct evdns_base *dnsbase = 0);
- ~TEvhttpClientChannel();
+ struct evdns_base *dnsbase = nullptr);
+ ~TEvhttpClientChannel() override;
- virtual void sendAndRecvMessage(const VoidCallback& cob,
+ void sendAndRecvMessage(const VoidCallback& cob,
apache::thrift::transport::TMemoryBuffer* sendBuf,
- apache::thrift::transport::TMemoryBuffer* recvBuf);
+ apache::thrift::transport::TMemoryBuffer* recvBuf) override;
- virtual void sendMessage(const VoidCallback& cob,
- apache::thrift::transport::TMemoryBuffer* message);
- virtual void recvMessage(const VoidCallback& cob,
- apache::thrift::transport::TMemoryBuffer* message);
+ void sendMessage(const VoidCallback& cob,
+ apache::thrift::transport::TMemoryBuffer* message) override;
+ void recvMessage(const VoidCallback& cob,
+ apache::thrift::transport::TMemoryBuffer* message) override;
void finish(struct evhttp_request* req);
// XXX
- virtual bool good() const { return true; }
- virtual bool error() const { return false; }
- virtual bool timedOut() const { return false; }
+ bool good() const override { return true; }
+ bool error() const override { return false; }
+ bool timedOut() const override { return false; }
private:
static void response(struct evhttp_request* req, void* arg);
diff --git a/lib/cpp/src/thrift/async/TEvhttpServer.cpp b/lib/cpp/src/thrift/async/TEvhttpServer.cpp
index d87e507..7d2cf21 100644
--- a/lib/cpp/src/thrift/async/TEvhttpServer.cpp
+++ b/lib/cpp/src/thrift/async/TEvhttpServer.cpp
@@ -20,7 +20,7 @@
#include <thrift/async/TEvhttpServer.h>
#include <thrift/async/TAsyncBufferProcessor.h>
#include <thrift/transport/TBufferTransports.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <evhttp.h>
#include <event2/buffer.h>
#include <event2/buffer_compat.h>
@@ -31,8 +31,7 @@
#endif
using apache::thrift::transport::TMemoryBuffer;
-using apache::thrift::stdcxx::scoped_ptr;
-using apache::thrift::stdcxx::shared_ptr;
+using std::shared_ptr;
namespace apache {
namespace thrift {
@@ -40,31 +39,31 @@
struct TEvhttpServer::RequestContext {
struct evhttp_request* req;
- stdcxx::shared_ptr<apache::thrift::transport::TMemoryBuffer> ibuf;
- stdcxx::shared_ptr<apache::thrift::transport::TMemoryBuffer> obuf;
+ std::shared_ptr<apache::thrift::transport::TMemoryBuffer> ibuf;
+ std::shared_ptr<apache::thrift::transport::TMemoryBuffer> obuf;
RequestContext(struct evhttp_request* req);
};
-TEvhttpServer::TEvhttpServer(stdcxx::shared_ptr<TAsyncBufferProcessor> processor)
- : processor_(processor), eb_(NULL), eh_(NULL) {
+TEvhttpServer::TEvhttpServer(std::shared_ptr<TAsyncBufferProcessor> processor)
+ : processor_(processor), eb_(nullptr), eh_(nullptr) {
}
-TEvhttpServer::TEvhttpServer(stdcxx::shared_ptr<TAsyncBufferProcessor> processor, int port)
- : processor_(processor), eb_(NULL), eh_(NULL) {
+TEvhttpServer::TEvhttpServer(std::shared_ptr<TAsyncBufferProcessor> processor, int port)
+ : processor_(processor), eb_(nullptr), eh_(nullptr) {
// Create event_base and evhttp.
eb_ = event_base_new();
- if (eb_ == NULL) {
+ if (eb_ == nullptr) {
throw TException("event_base_new failed");
}
eh_ = evhttp_new(eb_);
- if (eh_ == NULL) {
+ if (eh_ == nullptr) {
event_base_free(eb_);
throw TException("evhttp_new failed");
}
// Bind to port.
- int ret = evhttp_bind_socket(eh_, NULL, port);
+ int ret = evhttp_bind_socket(eh_, nullptr, port);
if (ret < 0) {
evhttp_free(eh_);
event_base_free(eb_);
@@ -78,16 +77,16 @@
}
TEvhttpServer::~TEvhttpServer() {
- if (eh_ != NULL) {
+ if (eh_ != nullptr) {
evhttp_free(eh_);
}
- if (eb_ != NULL) {
+ if (eb_ != nullptr) {
event_base_free(eb_);
}
}
int TEvhttpServer::serve() {
- if (eb_ == NULL) {
+ if (eb_ == nullptr) {
throw TException("Unexpected call to TEvhttpServer::serve");
}
return event_base_dispatch(eb_);
@@ -104,23 +103,23 @@
try {
static_cast<TEvhttpServer*>(self)->process(req);
} catch (std::exception& e) {
- evhttp_send_reply(req, HTTP_INTERNAL, e.what(), 0);
+ evhttp_send_reply(req, HTTP_INTERNAL, e.what(), nullptr);
}
}
void TEvhttpServer::process(struct evhttp_request* req) {
- RequestContext* ctx = new RequestContext(req);
- return processor_->process(apache::thrift::stdcxx::bind(&TEvhttpServer::complete,
+ auto* ctx = new RequestContext(req);
+ return processor_->process(std::bind(&TEvhttpServer::complete,
this,
ctx,
- apache::thrift::stdcxx::placeholders::_1),
+ std::placeholders::_1),
ctx->ibuf,
ctx->obuf);
}
void TEvhttpServer::complete(RequestContext* ctx, bool success) {
(void)success;
- scoped_ptr<RequestContext> ptr(ctx);
+ std::unique_ptr<RequestContext> ptr(ctx);
int code = success ? 200 : 400;
const char* reason = success ? "OK" : "Bad Request";
@@ -132,7 +131,7 @@
}
struct evbuffer* buf = evbuffer_new();
- if (buf == NULL) {
+ if (buf == nullptr) {
// TODO: Log an error.
std::cerr << "evbuffer_new failed " << __FILE__ << ":" << __LINE__ << std::endl;
} else {
@@ -148,7 +147,7 @@
}
evhttp_send_reply(ctx->req, code, reason, buf);
- if (buf != NULL) {
+ if (buf != nullptr) {
evbuffer_free(buf);
}
}
diff --git a/lib/cpp/src/thrift/async/TEvhttpServer.h b/lib/cpp/src/thrift/async/TEvhttpServer.h
index afc679c..c5bf3b6 100644
--- a/lib/cpp/src/thrift/async/TEvhttpServer.h
+++ b/lib/cpp/src/thrift/async/TEvhttpServer.h
@@ -20,7 +20,7 @@
#ifndef _THRIFT_TEVHTTP_SERVER_H_
#define _THRIFT_TEVHTTP_SERVER_H_ 1
-#include <thrift/stdcxx.h>
+#include <memory>
struct event_base;
struct evhttp;
@@ -41,14 +41,14 @@
* address of the server as the extra arg.
* Do not call "serve" on this server.
*/
- TEvhttpServer(stdcxx::shared_ptr<TAsyncBufferProcessor> processor);
+ TEvhttpServer(std::shared_ptr<TAsyncBufferProcessor> processor);
/**
* Create a TEvhttpServer with an embedded event_base and evhttp,
* listening on port and responding on the endpoint "/".
* Call "serve" on this server to serve forever.
*/
- TEvhttpServer(stdcxx::shared_ptr<TAsyncBufferProcessor> processor, int port);
+ TEvhttpServer(std::shared_ptr<TAsyncBufferProcessor> processor, int port);
~TEvhttpServer();
@@ -63,7 +63,7 @@
void process(struct evhttp_request* req);
void complete(RequestContext* ctx, bool success);
- stdcxx::shared_ptr<TAsyncBufferProcessor> processor_;
+ std::shared_ptr<TAsyncBufferProcessor> processor_;
struct event_base* eb_;
struct evhttp* eh_;
};
diff --git a/lib/cpp/src/thrift/concurrency/BoostMonitor.cpp b/lib/cpp/src/thrift/concurrency/BoostMonitor.cpp
deleted file mode 100644
index ebfa0b9..0000000
--- a/lib/cpp/src/thrift/concurrency/BoostMonitor.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * 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.
- */
-
-#include <thrift/thrift-config.h>
-
-#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/Exception.h>
-#include <thrift/concurrency/Util.h>
-#include <thrift/transport/PlatformSocket.h>
-#include <thrift/stdcxx.h>
-
-#include <assert.h>
-#include <boost/thread.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-
-namespace apache {
-namespace thrift {
-namespace concurrency {
-
-/**
- * Monitor implementation using the boost thread library
- *
- * @version $Id:$
- */
-class Monitor::Impl : public boost::condition_variable_any {
-
-public:
- Impl() : ownedMutex_(new Mutex()), mutex_(NULL) { init(ownedMutex_.get()); }
-
- Impl(Mutex* mutex) : mutex_(NULL) { init(mutex); }
-
- Impl(Monitor* monitor) : mutex_(NULL) { init(&(monitor->mutex())); }
-
- Mutex& mutex() { return *mutex_; }
- void lock() { mutex().lock(); }
- void unlock() { mutex().unlock(); }
-
- /**
- * Exception-throwing version of waitForTimeRelative(), called simply
- * wait(int64) for historical reasons. Timeout is in milliseconds.
- *
- * If the condition occurs, this function returns cleanly; on timeout or
- * error an exception is thrown.
- */
- void wait(int64_t timeout_ms) {
- int result = waitForTimeRelative(timeout_ms);
- if (result == THRIFT_ETIMEDOUT) {
- throw TimedOutException();
- } else if (result != 0) {
- throw TException("Monitor::wait() failed");
- }
- }
-
- /**
- * Waits until the specified timeout in milliseconds for the condition to
- * occur, or waits forever if timeout_ms == 0.
- *
- * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
- */
- int waitForTimeRelative(int64_t timeout_ms) {
- if (timeout_ms == 0LL) {
- return waitForever();
- }
-
- assert(mutex_);
- boost::timed_mutex* mutexImpl
- = reinterpret_cast<boost::timed_mutex*>(mutex_->getUnderlyingImpl());
- assert(mutexImpl);
-
- boost::timed_mutex::scoped_lock lock(*mutexImpl, boost::adopt_lock);
- int res
- = timed_wait(lock, boost::get_system_time() + boost::posix_time::milliseconds(timeout_ms))
- ? 0
- : THRIFT_ETIMEDOUT;
- lock.release();
- return res;
- }
-
- /**
- * Waits until the absolute time specified using struct THRIFT_TIMESPEC.
- * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
- */
- int waitForTime(const THRIFT_TIMESPEC* abstime) {
- struct timeval temp;
- temp.tv_sec = static_cast<long>(abstime->tv_sec);
- temp.tv_usec = static_cast<long>(abstime->tv_nsec) / 1000;
- return waitForTime(&temp);
- }
-
- /**
- * Waits until the absolute time specified using struct timeval.
- * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
- */
- int waitForTime(const struct timeval* abstime) {
- assert(mutex_);
- boost::timed_mutex* mutexImpl = static_cast<boost::timed_mutex*>(mutex_->getUnderlyingImpl());
- assert(mutexImpl);
-
- struct timeval currenttime;
- Util::toTimeval(currenttime, Util::currentTime());
-
- long tv_sec = static_cast<long>(abstime->tv_sec - currenttime.tv_sec);
- long tv_usec = static_cast<long>(abstime->tv_usec - currenttime.tv_usec);
- if (tv_sec < 0)
- tv_sec = 0;
- if (tv_usec < 0)
- tv_usec = 0;
-
- boost::timed_mutex::scoped_lock lock(*mutexImpl, boost::adopt_lock);
- int res = timed_wait(lock,
- boost::get_system_time() + boost::posix_time::seconds(tv_sec)
- + boost::posix_time::microseconds(tv_usec))
- ? 0
- : THRIFT_ETIMEDOUT;
- lock.release();
- return res;
- }
-
- /**
- * Waits forever until the condition occurs.
- * Returns 0 if condition occurs, or an error code otherwise.
- */
- int waitForever() {
- assert(mutex_);
- boost::timed_mutex* mutexImpl
- = reinterpret_cast<boost::timed_mutex*>(mutex_->getUnderlyingImpl());
- assert(mutexImpl);
-
- boost::timed_mutex::scoped_lock lock(*mutexImpl, boost::adopt_lock);
- ((boost::condition_variable_any*)this)->wait(lock);
- lock.release();
- return 0;
- }
-
- void notify() { notify_one(); }
-
- void notifyAll() { notify_all(); }
-
-private:
- void init(Mutex* mutex) { mutex_ = mutex; }
-
- stdcxx::scoped_ptr<Mutex> ownedMutex_;
- Mutex* mutex_;
-};
-
-Monitor::Monitor() : impl_(new Monitor::Impl()) {
-}
-Monitor::Monitor(Mutex* mutex) : impl_(new Monitor::Impl(mutex)) {
-}
-Monitor::Monitor(Monitor* monitor) : impl_(new Monitor::Impl(monitor)) {
-}
-
-Monitor::~Monitor() {
- delete impl_;
-}
-
-Mutex& Monitor::mutex() const {
- return const_cast<Monitor::Impl*>(impl_)->mutex();
-}
-
-void Monitor::lock() const {
- const_cast<Monitor::Impl*>(impl_)->lock();
-}
-
-void Monitor::unlock() const {
- const_cast<Monitor::Impl*>(impl_)->unlock();
-}
-
-void Monitor::wait(int64_t timeout) const {
- const_cast<Monitor::Impl*>(impl_)->wait(timeout);
-}
-
-int Monitor::waitForTime(const THRIFT_TIMESPEC* abstime) const {
- return const_cast<Monitor::Impl*>(impl_)->waitForTime(abstime);
-}
-
-int Monitor::waitForTime(const timeval* abstime) const {
- return const_cast<Monitor::Impl*>(impl_)->waitForTime(abstime);
-}
-
-int Monitor::waitForTimeRelative(int64_t timeout_ms) const {
- return const_cast<Monitor::Impl*>(impl_)->waitForTimeRelative(timeout_ms);
-}
-
-int Monitor::waitForever() const {
- return const_cast<Monitor::Impl*>(impl_)->waitForever();
-}
-
-void Monitor::notify() const {
- const_cast<Monitor::Impl*>(impl_)->notify();
-}
-
-void Monitor::notifyAll() const {
- const_cast<Monitor::Impl*>(impl_)->notifyAll();
-}
-}
-}
-} // apache::thrift::concurrency
diff --git a/lib/cpp/src/thrift/concurrency/BoostMutex.cpp b/lib/cpp/src/thrift/concurrency/BoostMutex.cpp
deleted file mode 100644
index 4e556df..0000000
--- a/lib/cpp/src/thrift/concurrency/BoostMutex.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.
- */
-
-#include <thrift/thrift-config.h>
-
-#include <thrift/concurrency/Mutex.h>
-#include <thrift/concurrency/Util.h>
-#include <thrift/Thrift.h>
-
-#include <cassert>
-#include <boost/thread.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-
-namespace apache {
-namespace thrift {
-namespace concurrency {
-
-/**
- * Implementation of Mutex class using boost::timed_mutex
- *
- * Methods throw boost::lock_error on error.
- *
- * @version $Id:$
- */
-class Mutex::impl : public boost::timed_mutex {};
-
-Mutex::Mutex(Initializer init) : impl_(new Mutex::impl()) {
- THRIFT_UNUSED_VARIABLE(init);
-}
-
-void* Mutex::getUnderlyingImpl() const {
- return impl_.get();
-}
-
-void Mutex::lock() const {
- impl_->lock();
-}
-
-bool Mutex::trylock() const {
- return impl_->try_lock();
-}
-
-bool Mutex::timedlock(int64_t ms) const {
- return impl_->timed_lock(boost::get_system_time() + boost::posix_time::milliseconds(ms));
-}
-
-void Mutex::unlock() const {
- impl_->unlock();
-}
-
-void Mutex::DEFAULT_INITIALIZER(void* arg) {
- THRIFT_UNUSED_VARIABLE(arg);
-}
-}
-}
-} // apache::thrift::concurrency
diff --git a/lib/cpp/src/thrift/concurrency/BoostThreadFactory.cpp b/lib/cpp/src/thrift/concurrency/BoostThreadFactory.cpp
deleted file mode 100644
index d7d8d54..0000000
--- a/lib/cpp/src/thrift/concurrency/BoostThreadFactory.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * 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.
- */
-
-#include <thrift/thrift-config.h>
-
-#if USE_BOOST_THREAD
-
-#include <thrift/concurrency/BoostThreadFactory.h>
-#include <thrift/concurrency/Exception.h>
-#include <thrift/stdcxx.h>
-#include <cassert>
-
-#include <boost/thread.hpp>
-
-namespace apache {
-namespace thrift {
-
-using stdcxx::bind;
-using stdcxx::scoped_ptr;
-using stdcxx::shared_ptr;
-using stdcxx::weak_ptr;
-
-namespace concurrency {
-
-/**
- * The boost thread class.
- *
- * @version $Id:$
- */
-class BoostThread : public Thread {
-public:
- enum STATE { uninitialized, starting, started, stopping, stopped };
-
- static void* threadMain(void* arg);
-
-private:
- scoped_ptr<boost::thread> thread_;
- Monitor monitor_;
- STATE state_;
- weak_ptr<BoostThread> self_;
- bool detached_;
-
-public:
- BoostThread(bool detached, shared_ptr<Runnable> runnable)
- : state_(uninitialized), detached_(detached) {
- this->Thread::runnable(runnable);
- }
-
- ~BoostThread() {
- if (!detached_ && thread_->joinable()) {
- try {
- join();
- } catch (...) {
- // We're really hosed.
- }
- }
- }
-
- STATE getState() const
- {
- Synchronized sync(monitor_);
- return state_;
- }
-
- void setState(STATE newState)
- {
- Synchronized sync(monitor_);
- state_ = newState;
-
- // unblock start() with the knowledge that the thread has actually
- // started running, which avoids a race in detached threads.
- if (newState == started) {
- monitor_.notify();
- }
- }
-
- void start() {
- // Create reference
- shared_ptr<BoostThread>* selfRef = new shared_ptr<BoostThread>();
- *selfRef = self_.lock();
-
- setState(starting);
-
- Synchronized sync(monitor_);
-
- thread_.reset(new boost::thread(bind(threadMain, (void*)selfRef)));
-
- if (detached_)
- thread_->detach();
-
- // Wait for the thread to start and get far enough to grab everything
- // that it needs from the calling context, thus absolving the caller
- // from being required to hold on to runnable indefinitely.
- monitor_.wait();
- }
-
- void join() {
- if (!detached_ && getState() != uninitialized) {
- thread_->join();
- }
- }
-
- Thread::id_t getId() { return thread_.get() ? thread_->get_id() : boost::thread::id(); }
-
- shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
-
- void runnable(shared_ptr<Runnable> value) { Thread::runnable(value); }
-
- void weakRef(shared_ptr<BoostThread> self) {
- assert(self.get() == this);
- self_ = weak_ptr<BoostThread>(self);
- }
-};
-
-void* BoostThread::threadMain(void* arg) {
- shared_ptr<BoostThread> thread = *(shared_ptr<BoostThread>*)arg;
- delete reinterpret_cast<shared_ptr<BoostThread>*>(arg);
-
- thread->setState(started);
- thread->runnable()->run();
-
- if (thread->getState() != stopping && thread->getState() != stopped) {
- thread->setState(stopping);
- }
- return (void*)0;
-}
-
-BoostThreadFactory::BoostThreadFactory(bool detached)
- : ThreadFactory(detached) {
-}
-
-shared_ptr<Thread> BoostThreadFactory::newThread(shared_ptr<Runnable> runnable) const {
- shared_ptr<BoostThread> result = shared_ptr<BoostThread>(new BoostThread(isDetached(), runnable));
- result->weakRef(result);
- runnable->thread(result);
- return result;
-}
-
-Thread::id_t BoostThreadFactory::getCurrentThreadId() const {
- return boost::this_thread::get_id();
-}
-}
-}
-} // apache::thrift::concurrency
-
-#endif // USE_BOOST_THREAD
diff --git a/lib/cpp/src/thrift/concurrency/BoostThreadFactory.h b/lib/cpp/src/thrift/concurrency/BoostThreadFactory.h
deleted file mode 100644
index bf11a70..0000000
--- a/lib/cpp/src/thrift/concurrency/BoostThreadFactory.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _THRIFT_CONCURRENCY_BOOSTTHREADFACTORY_H_
-#define _THRIFT_CONCURRENCY_BOOSTTHREADFACTORY_H_ 1
-
-#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/Thread.h>
-#include <thrift/stdcxx.h>
-
-namespace apache {
-namespace thrift {
-namespace concurrency {
-
-/**
- * A thread factory to create posix threads
- *
- * @version $Id:$
- */
-class BoostThreadFactory : public ThreadFactory {
-
-public:
- /**
- * Boost thread factory. All threads created by a factory are reference-counted
- * via stdcxx::shared_ptr. The factory guarantees that threads and the Runnable tasks they
- * host will be properly cleaned up once the last strong reference to both is given up.
- *
- * Threads are created with the specified boost policy, priority, stack-size. A detachable thread
- * is not joinable.
- *
- * By default threads are not joinable.
- */
-
- BoostThreadFactory(bool detached = true);
-
- // From ThreadFactory;
- stdcxx::shared_ptr<Thread> newThread(stdcxx::shared_ptr<Runnable> runnable) const;
-
- // From ThreadFactory;
- Thread::id_t getCurrentThreadId() const;
-};
-
-}
-}
-} // apache::thrift::concurrency
-
-#endif // #ifndef _THRIFT_CONCURRENCY_BOOSTTHREADFACTORY_H_
diff --git a/lib/cpp/src/thrift/concurrency/Exception.h b/lib/cpp/src/thrift/concurrency/Exception.h
index 6438fda..947fc9f 100644
--- a/lib/cpp/src/thrift/concurrency/Exception.h
+++ b/lib/cpp/src/thrift/concurrency/Exception.h
@@ -35,7 +35,7 @@
class IllegalStateException : public apache::thrift::TException {
public:
- IllegalStateException() {}
+ IllegalStateException() = default;
IllegalStateException(const std::string& message) : TException(message) {}
};
@@ -53,7 +53,7 @@
class SystemResourceException : public apache::thrift::TException {
public:
- SystemResourceException() {}
+ SystemResourceException() = default;
SystemResourceException(const std::string& message) : TException(message) {}
};
diff --git a/lib/cpp/src/thrift/concurrency/FunctionRunner.h b/lib/cpp/src/thrift/concurrency/FunctionRunner.h
index eabf019..4688344 100644
--- a/lib/cpp/src/thrift/concurrency/FunctionRunner.h
+++ b/lib/cpp/src/thrift/concurrency/FunctionRunner.h
@@ -21,7 +21,7 @@
#define _THRIFT_CONCURRENCY_FUNCTION_RUNNER_H 1
#include <thrift/concurrency/Thread.h>
-#include <thrift/stdcxx.h>
+#include <memory>
namespace apache {
namespace thrift {
@@ -44,7 +44,7 @@
* A* a = new A();
* // To create a thread that executes a.foo() every 100 milliseconds:
* factory->newThread(FunctionRunner::create(
- * apache::thrift::stdcxx::bind(&A::foo, a), 100))->start();
+ * std::bind(&A::foo, a), 100))->start();
*
*/
@@ -53,20 +53,20 @@
// This is the type of callback 'pthread_create()' expects.
typedef void* (*PthreadFuncPtr)(void* arg);
// This a fully-generic void(void) callback for custom bindings.
- typedef stdcxx::function<void()> VoidFunc;
+ typedef std::function<void()> VoidFunc;
- typedef stdcxx::function<bool()> BoolFunc;
+ typedef std::function<bool()> BoolFunc;
/**
* Syntactic sugar to make it easier to create new FunctionRunner
* objects wrapped in shared_ptr.
*/
- static stdcxx::shared_ptr<FunctionRunner> create(const VoidFunc& cob) {
- return stdcxx::shared_ptr<FunctionRunner>(new FunctionRunner(cob));
+ static std::shared_ptr<FunctionRunner> create(const VoidFunc& cob) {
+ return std::shared_ptr<FunctionRunner>(new FunctionRunner(cob));
}
- static stdcxx::shared_ptr<FunctionRunner> create(PthreadFuncPtr func, void* arg) {
- return stdcxx::shared_ptr<FunctionRunner>(new FunctionRunner(func, arg));
+ static std::shared_ptr<FunctionRunner> create(PthreadFuncPtr func, void* arg) {
+ return std::shared_ptr<FunctionRunner>(new FunctionRunner(func, arg));
}
private:
@@ -81,7 +81,7 @@
* execute the given callback. Note that the 'void*' return value is ignored.
*/
FunctionRunner(PthreadFuncPtr func, void* arg)
- : func_(stdcxx::bind(pthread_func_wrapper, func, arg)), intervalMs_(-1) {}
+ : func_(std::bind(pthread_func_wrapper, func, arg)), intervalMs_(-1) {}
/**
* Given a generic callback, this FunctionRunner will execute it.
@@ -96,7 +96,7 @@
*/
FunctionRunner(const BoolFunc& cob, int intervalMs) : repFunc_(cob), intervalMs_(intervalMs) {}
- void run() {
+ void run() override {
if (repFunc_) {
while (repFunc_()) {
THRIFT_SLEEP_USEC(intervalMs_ * 1000);
diff --git a/lib/cpp/src/thrift/concurrency/Monitor.cpp b/lib/cpp/src/thrift/concurrency/Monitor.cpp
index af4fcd0..dc92efd 100644
--- a/lib/cpp/src/thrift/concurrency/Monitor.cpp
+++ b/lib/cpp/src/thrift/concurrency/Monitor.cpp
@@ -21,45 +21,37 @@
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/Exception.h>
-#include <thrift/concurrency/Util.h>
#include <thrift/transport/PlatformSocket.h>
-#include <thrift/stdcxx.h>
-
#include <assert.h>
-#include <iostream>
-
-#include <pthread.h>
+#include <condition_variable>
+#include <chrono>
+#include <thread>
+#include <mutex>
namespace apache {
namespace thrift {
-
-using stdcxx::scoped_ptr;
-using stdcxx::shared_ptr;
-
namespace concurrency {
/**
- * Monitor implementation using the POSIX pthread library
+ * Monitor implementation using the std thread library
*
* @version $Id:$
*/
class Monitor::Impl {
public:
- Impl() : ownedMutex_(new Mutex()), mutex_(NULL), condInitialized_(false) {
- init(ownedMutex_.get());
+ Impl() : ownedMutex_(new Mutex()), conditionVariable_(), mutex_(nullptr) { init(ownedMutex_.get()); }
+
+ Impl(Mutex* mutex) : ownedMutex_(), conditionVariable_(), mutex_(nullptr) { init(mutex); }
+
+ Impl(Monitor* monitor) : ownedMutex_(), conditionVariable_(), mutex_(nullptr) {
+ init(&(monitor->mutex()));
}
- Impl(Mutex* mutex) : mutex_(NULL), condInitialized_(false) { init(mutex); }
-
- Impl(Monitor* monitor) : mutex_(NULL), condInitialized_(false) { init(&(monitor->mutex())); }
-
- ~Impl() { cleanup(); }
-
Mutex& mutex() { return *mutex_; }
- void lock() { mutex().lock(); }
- void unlock() { mutex().unlock(); }
+ void lock() { mutex_->lock(); }
+ void unlock() { mutex_->unlock(); }
/**
* Exception-throwing version of waitForTimeRelative(), called simply
@@ -68,106 +60,78 @@
* If the condition occurs, this function returns cleanly; on timeout or
* error an exception is thrown.
*/
- void wait(int64_t timeout_ms) const {
- int result = waitForTimeRelative(timeout_ms);
+ void wait(const std::chrono::milliseconds &timeout) {
+ int result = waitForTimeRelative(timeout);
if (result == THRIFT_ETIMEDOUT) {
- // pthread_cond_timedwait has been observed to return early on
- // various platforms, so comment out this assert.
- // assert(Util::currentTime() >= (now + timeout));
throw TimedOutException();
} else if (result != 0) {
- throw TException("pthread_cond_wait() or pthread_cond_timedwait() failed");
+ throw TException("Monitor::wait() failed");
}
}
/**
* Waits until the specified timeout in milliseconds for the condition to
- * occur, or waits forever if timeout_ms == 0.
+ * occur, or waits forever if timeout is zero.
*
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
*/
- int waitForTimeRelative(int64_t timeout_ms) const {
- if (timeout_ms == 0LL) {
+ int waitForTimeRelative(const std::chrono::milliseconds &timeout) {
+ if (timeout.count() == 0) {
return waitForever();
}
- struct THRIFT_TIMESPEC abstime;
- Util::toTimespec(abstime, Util::currentTime() + timeout_ms);
- return waitForTime(&abstime);
+ assert(mutex_);
+ auto* mutexImpl = static_cast<std::timed_mutex*>(mutex_->getUnderlyingImpl());
+ assert(mutexImpl);
+
+ std::unique_lock<std::timed_mutex> lock(*mutexImpl, std::adopt_lock);
+ bool timedout = (conditionVariable_.wait_for(lock, timeout)
+ == std::cv_status::timeout);
+ lock.release();
+ return (timedout ? THRIFT_ETIMEDOUT : 0);
}
/**
- * Waits until the absolute time specified using struct THRIFT_TIMESPEC.
+ * Waits until the absolute time specified by abstime.
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
*/
- int waitForTime(const THRIFT_TIMESPEC* abstime) const {
+ int waitForTime(const std::chrono::time_point<std::chrono::steady_clock>& abstime) {
assert(mutex_);
- pthread_mutex_t* mutexImpl = reinterpret_cast<pthread_mutex_t*>(mutex_->getUnderlyingImpl());
+ auto* mutexImpl = static_cast<std::timed_mutex*>(mutex_->getUnderlyingImpl());
assert(mutexImpl);
- // XXX Need to assert that caller owns mutex
- return pthread_cond_timedwait(&pthread_cond_, mutexImpl, abstime);
+ std::unique_lock<std::timed_mutex> lock(*mutexImpl, std::adopt_lock);
+ bool timedout = (conditionVariable_.wait_until(lock, abstime)
+ == std::cv_status::timeout);
+ lock.release();
+ return (timedout ? THRIFT_ETIMEDOUT : 0);
}
- int waitForTime(const struct timeval* abstime) const {
- struct THRIFT_TIMESPEC temp;
- temp.tv_sec = abstime->tv_sec;
- temp.tv_nsec = abstime->tv_usec * 1000;
- return waitForTime(&temp);
- }
/**
* Waits forever until the condition occurs.
* Returns 0 if condition occurs, or an error code otherwise.
*/
- int waitForever() const {
+ int waitForever() {
assert(mutex_);
- pthread_mutex_t* mutexImpl = reinterpret_cast<pthread_mutex_t*>(mutex_->getUnderlyingImpl());
+ auto* mutexImpl = static_cast<std::timed_mutex*>(mutex_->getUnderlyingImpl());
assert(mutexImpl);
- return pthread_cond_wait(&pthread_cond_, mutexImpl);
+
+ std::unique_lock<std::timed_mutex> lock(*mutexImpl, std::adopt_lock);
+ conditionVariable_.wait(lock);
+ lock.release();
+ return 0;
}
- void notify() {
- // XXX Need to assert that caller owns mutex
- int iret = pthread_cond_signal(&pthread_cond_);
- THRIFT_UNUSED_VARIABLE(iret);
- assert(iret == 0);
- }
+ void notify() { conditionVariable_.notify_one(); }
- void notifyAll() {
- // XXX Need to assert that caller owns mutex
- int iret = pthread_cond_broadcast(&pthread_cond_);
- THRIFT_UNUSED_VARIABLE(iret);
- assert(iret == 0);
- }
+ void notifyAll() { conditionVariable_.notify_all(); }
private:
- void init(Mutex* mutex) {
- mutex_ = mutex;
+ void init(Mutex* mutex) { mutex_ = mutex; }
- if (pthread_cond_init(&pthread_cond_, NULL) == 0) {
- condInitialized_ = true;
- }
-
- if (!condInitialized_) {
- cleanup();
- throw SystemResourceException();
- }
- }
-
- void cleanup() {
- if (condInitialized_) {
- condInitialized_ = false;
- int iret = pthread_cond_destroy(&pthread_cond_);
- THRIFT_UNUSED_VARIABLE(iret);
- assert(iret == 0);
- }
- }
-
- scoped_ptr<Mutex> ownedMutex_;
+ const std::unique_ptr<Mutex> ownedMutex_;
+ std::condition_variable_any conditionVariable_;
Mutex* mutex_;
-
- mutable pthread_cond_t pthread_cond_;
- mutable bool condInitialized_;
};
Monitor::Monitor() : impl_(new Monitor::Impl()) {
@@ -182,43 +146,39 @@
}
Mutex& Monitor::mutex() const {
- return impl_->mutex();
+ return const_cast<Monitor::Impl*>(impl_)->mutex();
}
void Monitor::lock() const {
- impl_->lock();
+ const_cast<Monitor::Impl*>(impl_)->lock();
}
void Monitor::unlock() const {
- impl_->unlock();
+ const_cast<Monitor::Impl*>(impl_)->unlock();
}
-void Monitor::wait(int64_t timeout) const {
- impl_->wait(timeout);
+void Monitor::wait(const std::chrono::milliseconds &timeout) const {
+ const_cast<Monitor::Impl*>(impl_)->wait(timeout);
}
-int Monitor::waitForTime(const THRIFT_TIMESPEC* abstime) const {
- return impl_->waitForTime(abstime);
+int Monitor::waitForTime(const std::chrono::time_point<std::chrono::steady_clock>& abstime) const {
+ return const_cast<Monitor::Impl*>(impl_)->waitForTime(abstime);
}
-int Monitor::waitForTime(const timeval* abstime) const {
- return impl_->waitForTime(abstime);
-}
-
-int Monitor::waitForTimeRelative(int64_t timeout_ms) const {
- return impl_->waitForTimeRelative(timeout_ms);
+int Monitor::waitForTimeRelative(const std::chrono::milliseconds &timeout) const {
+ return const_cast<Monitor::Impl*>(impl_)->waitForTimeRelative(timeout);
}
int Monitor::waitForever() const {
- return impl_->waitForever();
+ return const_cast<Monitor::Impl*>(impl_)->waitForever();
}
void Monitor::notify() const {
- impl_->notify();
+ const_cast<Monitor::Impl*>(impl_)->notify();
}
void Monitor::notifyAll() const {
- impl_->notifyAll();
+ const_cast<Monitor::Impl*>(impl_)->notifyAll();
}
}
}
diff --git a/lib/cpp/src/thrift/concurrency/Monitor.h b/lib/cpp/src/thrift/concurrency/Monitor.h
index 2399a98..b3939cb 100644
--- a/lib/cpp/src/thrift/concurrency/Monitor.h
+++ b/lib/cpp/src/thrift/concurrency/Monitor.h
@@ -20,15 +20,10 @@
#ifndef _THRIFT_CONCURRENCY_MONITOR_H_
#define _THRIFT_CONCURRENCY_MONITOR_H_ 1
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
+#include <chrono>
#include <thrift/concurrency/Exception.h>
#include <thrift/concurrency/Mutex.h>
-#include <boost/utility.hpp>
-
namespace apache {
namespace thrift {
namespace concurrency {
@@ -73,23 +68,19 @@
/**
* Waits a maximum of the specified timeout in milliseconds for the condition
- * to occur, or waits forever if timeout_ms == 0.
+ * to occur, or waits forever if timeout is zero.
*
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
*/
- int waitForTimeRelative(int64_t timeout_ms) const;
+ int waitForTimeRelative(const std::chrono::milliseconds &timeout) const;
+
+ int waitForTimeRelative(uint64_t timeout_ms) const { return waitForTimeRelative(std::chrono::milliseconds(timeout_ms)); }
/**
- * Waits until the absolute time specified using struct THRIFT_TIMESPEC.
+ * Waits until the absolute time specified by abstime.
* Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
*/
- int waitForTime(const THRIFT_TIMESPEC* abstime) const;
-
- /**
- * Waits until the absolute time specified using struct timeval.
- * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
- */
- int waitForTime(const struct timeval* abstime) const;
+ int waitForTime(const std::chrono::time_point<std::chrono::steady_clock>& abstime) const;
/**
* Waits forever until the condition occurs.
@@ -99,12 +90,14 @@
/**
* Exception-throwing version of waitForTimeRelative(), called simply
- * wait(int64) for historical reasons. Timeout is in milliseconds.
+ * wait(std::chrono::milliseconds) for historical reasons. Timeout is in milliseconds.
*
- * If the condition occurs, this function returns cleanly; on timeout or
+ * If the condition occurs, this function returns cleanly; on timeout or
* error an exception is thrown.
*/
- void wait(int64_t timeout_ms = 0LL) const;
+ void wait(const std::chrono::milliseconds &timeout) const;
+
+ void wait(uint64_t timeout_ms = 0ULL) const { this->wait(std::chrono::milliseconds(timeout_ms)); }
/** Wakes up one thread waiting on this monitor. */
virtual void notify() const;
diff --git a/lib/cpp/src/thrift/concurrency/Mutex.cpp b/lib/cpp/src/thrift/concurrency/Mutex.cpp
index a526461..7580283 100644
--- a/lib/cpp/src/thrift/concurrency/Mutex.cpp
+++ b/lib/cpp/src/thrift/concurrency/Mutex.cpp
@@ -17,202 +17,29 @@
* under the License.
*/
-// needed to test for pthread implementation capabilities:
-#define __USE_GNU
-
-#include <thrift/thrift-config.h>
-
-#include <thrift/Thrift.h>
-#include <thrift/concurrency/Exception.h>
#include <thrift/concurrency/Mutex.h>
-#include <thrift/concurrency/Util.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-
-#include <boost/format.hpp>
+#include <chrono>
+#include <mutex>
namespace apache {
namespace thrift {
namespace concurrency {
-// Enable this to turn on mutex contention profiling support
-// #define THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
-
-#ifdef THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
-
-static int32_t mutexProfilingCounter = 0;
-static int32_t mutexProfilingSampleRate = 0;
-static MutexWaitCallback mutexProfilingCallback = 0;
-
-void enableMutexProfiling(int32_t profilingSampleRate, MutexWaitCallback callback) {
- mutexProfilingSampleRate = profilingSampleRate;
- mutexProfilingCallback = callback;
-}
-
-#define PROFILE_MUTEX_START_LOCK() int64_t _lock_startTime = maybeGetProfilingStartTime();
-
-#define PROFILE_MUTEX_NOT_LOCKED() \
- do { \
- if (_lock_startTime > 0) { \
- int64_t endTime = Util::currentTimeUsec(); \
- (*mutexProfilingCallback)(this, endTime - _lock_startTime); \
- } \
- } while (0)
-
-#define PROFILE_MUTEX_LOCKED() \
- do { \
- profileTime_ = _lock_startTime; \
- if (profileTime_ > 0) { \
- profileTime_ = Util::currentTimeUsec() - profileTime_; \
- } \
- } while (0)
-
-#define PROFILE_MUTEX_START_UNLOCK() \
- int64_t _temp_profileTime = profileTime_; \
- profileTime_ = 0;
-
-#define PROFILE_MUTEX_UNLOCKED() \
- do { \
- if (_temp_profileTime > 0) { \
- (*mutexProfilingCallback)(this, _temp_profileTime); \
- } \
- } while (0)
-
-static inline int64_t maybeGetProfilingStartTime() {
- if (mutexProfilingSampleRate && mutexProfilingCallback) {
- // This block is unsynchronized, but should produce a reasonable sampling
- // rate on most architectures. The main race conditions are the gap
- // between the decrement and the test, the non-atomicity of decrement, and
- // potential caching of different values at different CPUs.
- //
- // - if two decrements race, the likeliest result is that the counter
- // decrements slowly (perhaps much more slowly) than intended.
- //
- // - many threads could potentially decrement before resetting the counter
- // to its large value, causing each additional incoming thread to
- // profile every call. This situation is unlikely to persist for long
- // as the critical gap is quite short, but profiling could be bursty.
- sig_atomic_t localValue = --mutexProfilingCounter;
- if (localValue <= 0) {
- mutexProfilingCounter = mutexProfilingSampleRate;
- return Util::currentTimeUsec();
- }
- }
-
- return 0;
-}
-
-#else
-#define PROFILE_MUTEX_START_LOCK()
-#define PROFILE_MUTEX_NOT_LOCKED()
-#define PROFILE_MUTEX_LOCKED()
-#define PROFILE_MUTEX_START_UNLOCK()
-#define PROFILE_MUTEX_UNLOCKED()
-#endif // THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
-
-#define EINTR_LOOP(_CALL) int ret; do { ret = _CALL; } while (ret == EINTR)
-#define ABORT_ONFAIL(_CALL) { EINTR_LOOP(_CALL); if (ret) { abort(); } }
-#define THROW_SRE(_CALLSTR, RET) { throw SystemResourceException(boost::str(boost::format("%1% returned %2% (%3%)") % _CALLSTR % RET % ::strerror(RET))); }
-#define THROW_SRE_ONFAIL(_CALL) { EINTR_LOOP(_CALL); if (ret) { THROW_SRE(#_CALL, ret); } }
-#define THROW_SRE_TRYFAIL(_CALL) { EINTR_LOOP(_CALL); if (ret == 0) { return true; } else if (ret == EBUSY) { return false; } THROW_SRE(#_CALL, ret); }
-
/**
- * Implementation of Mutex class using POSIX mutex
+ * Implementation of Mutex class using C++11 std::timed_mutex
*
- * Throws apache::thrift::concurrency::SystemResourceException on error.
+ * Methods throw std::system_error on error.
*
* @version $Id:$
*/
-class Mutex::impl {
-public:
- impl(Initializer init) : initialized_(false) {
-#ifdef THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
- profileTime_ = 0;
-#endif
- init(&pthread_mutex_);
- initialized_ = true;
- }
+class Mutex::impl : public std::timed_mutex {};
- ~impl() {
- if (initialized_) {
- initialized_ = false;
- ABORT_ONFAIL(pthread_mutex_destroy(&pthread_mutex_));
- }
- }
-
- void lock() const {
- PROFILE_MUTEX_START_LOCK();
- THROW_SRE_ONFAIL(pthread_mutex_lock(&pthread_mutex_));
- PROFILE_MUTEX_LOCKED();
- }
-
- bool trylock() const {
- THROW_SRE_TRYFAIL(pthread_mutex_trylock(&pthread_mutex_));
- }
-
- bool timedlock(int64_t milliseconds) const {
-#if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 200112L
- PROFILE_MUTEX_START_LOCK();
-
- struct THRIFT_TIMESPEC ts;
- Util::toTimespec(ts, milliseconds + Util::currentTime());
- EINTR_LOOP(pthread_mutex_timedlock(&pthread_mutex_, &ts));
- if (ret == 0) {
- PROFILE_MUTEX_LOCKED();
- return true;
- } else if (ret == ETIMEDOUT) {
- PROFILE_MUTEX_NOT_LOCKED();
- return false;
- }
-
- THROW_SRE("pthread_mutex_timedlock(&pthread_mutex_, &ts)", ret);
-#else
- /* Otherwise follow solution used by Mono for Android */
- struct THRIFT_TIMESPEC sleepytime, now, to;
-
- /* This is just to avoid a completely busy wait */
- sleepytime.tv_sec = 0;
- sleepytime.tv_nsec = 10000000L; /* 10ms */
-
- Util::toTimespec(to, milliseconds + Util::currentTime());
-
- while ((trylock()) == false) {
- Util::toTimespec(now, Util::currentTime());
- if (now.tv_sec >= to.tv_sec && now.tv_nsec >= to.tv_nsec) {
- return false;
- }
- nanosleep(&sleepytime, NULL);
- }
-
- return true;
-#endif
- }
-
- void unlock() const {
- PROFILE_MUTEX_START_UNLOCK();
- THROW_SRE_ONFAIL(pthread_mutex_unlock(&pthread_mutex_));
- PROFILE_MUTEX_UNLOCKED();
- }
-
- void* getUnderlyingImpl() const { return (void*)&pthread_mutex_; }
-
-private:
- mutable pthread_mutex_t pthread_mutex_;
- mutable bool initialized_;
-#ifdef THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
- mutable int64_t profileTime_;
-#endif
-};
-
-Mutex::Mutex(Initializer init) : impl_(new Mutex::impl(init)) {
+Mutex::Mutex() : impl_(new Mutex::impl()) {
}
void* Mutex::getUnderlyingImpl() const {
- return impl_->getUnderlyingImpl();
+ return impl_.get();
}
void Mutex::lock() const {
@@ -220,161 +47,17 @@
}
bool Mutex::trylock() const {
- return impl_->trylock();
+ return impl_->try_lock();
}
bool Mutex::timedlock(int64_t ms) const {
- return impl_->timedlock(ms);
+ return impl_->try_lock_for(std::chrono::milliseconds(ms));
}
void Mutex::unlock() const {
impl_->unlock();
}
-void Mutex::DEFAULT_INITIALIZER(void* arg) {
- pthread_mutex_t* pthread_mutex = (pthread_mutex_t*)arg;
- THROW_SRE_ONFAIL(pthread_mutex_init(pthread_mutex, NULL));
-}
-
-#if defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) || defined(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP) || defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
-static void init_with_kind(pthread_mutex_t* mutex, int kind) {
- pthread_mutexattr_t mutexattr;
- THROW_SRE_ONFAIL(pthread_mutexattr_init(&mutexattr));
- THROW_SRE_ONFAIL(pthread_mutexattr_settype(&mutexattr, kind));
- THROW_SRE_ONFAIL(pthread_mutex_init(mutex, &mutexattr));
- THROW_SRE_ONFAIL(pthread_mutexattr_destroy(&mutexattr));
-}
-#endif
-
-#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
-void Mutex::ADAPTIVE_INITIALIZER(void* arg) {
- // From mysql source: mysys/my_thr_init.c
- // Set mutex type to "fast" a.k.a "adaptive"
- //
- // In this case the thread may steal the mutex from some other thread
- // that is waiting for the same mutex. This will save us some
- // context switches but may cause a thread to 'starve forever' while
- // waiting for the mutex (not likely if the code within the mutex is
- // short).
- init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_ADAPTIVE_NP);
-}
-#endif
-
-#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-void Mutex::ERRORCHECK_INITIALIZER(void* arg) {
- init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_ERRORCHECK);
-}
-#endif
-
-#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
-void Mutex::RECURSIVE_INITIALIZER(void* arg) {
- init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP);
-}
-#endif
-
-/**
- * Implementation of ReadWriteMutex class using POSIX rw lock
- *
- * @version $Id:$
- */
-class ReadWriteMutex::impl {
-public:
- impl() : initialized_(false) {
-#ifdef THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
- profileTime_ = 0;
-#endif
- THROW_SRE_ONFAIL(pthread_rwlock_init(&rw_lock_, NULL));
- initialized_ = true;
- }
-
- ~impl() {
- if (initialized_) {
- initialized_ = false;
- ABORT_ONFAIL(pthread_rwlock_destroy(&rw_lock_));
- }
- }
-
- void acquireRead() const {
- PROFILE_MUTEX_START_LOCK();
- THROW_SRE_ONFAIL(pthread_rwlock_rdlock(&rw_lock_));
- PROFILE_MUTEX_NOT_LOCKED(); // not exclusive, so use not-locked path
- }
-
- void acquireWrite() const {
- PROFILE_MUTEX_START_LOCK();
- THROW_SRE_ONFAIL(pthread_rwlock_wrlock(&rw_lock_));
- PROFILE_MUTEX_LOCKED();
- }
-
- bool attemptRead() const { THROW_SRE_TRYFAIL(pthread_rwlock_tryrdlock(&rw_lock_)); }
-
- bool attemptWrite() const { THROW_SRE_TRYFAIL(pthread_rwlock_trywrlock(&rw_lock_)); }
-
- void release() const {
- PROFILE_MUTEX_START_UNLOCK();
- THROW_SRE_ONFAIL(pthread_rwlock_unlock(&rw_lock_));
- PROFILE_MUTEX_UNLOCKED();
- }
-
-private:
- mutable pthread_rwlock_t rw_lock_;
- mutable bool initialized_;
-#ifdef THRIFT_PTHREAD_MUTEX_CONTENTION_PROFILING
- mutable int64_t profileTime_;
-#endif
-};
-
-ReadWriteMutex::ReadWriteMutex() : impl_(new ReadWriteMutex::impl()) {
-}
-
-void ReadWriteMutex::acquireRead() const {
- impl_->acquireRead();
-}
-
-void ReadWriteMutex::acquireWrite() const {
- impl_->acquireWrite();
-}
-
-bool ReadWriteMutex::attemptRead() const {
- return impl_->attemptRead();
-}
-
-bool ReadWriteMutex::attemptWrite() const {
- return impl_->attemptWrite();
-}
-
-void ReadWriteMutex::release() const {
- impl_->release();
-}
-
-NoStarveReadWriteMutex::NoStarveReadWriteMutex() : writerWaiting_(false) {
-}
-
-void NoStarveReadWriteMutex::acquireRead() const {
- if (writerWaiting_) {
- // writer is waiting, block on the writer's mutex until he's done with it
- mutex_.lock();
- mutex_.unlock();
- }
-
- ReadWriteMutex::acquireRead();
-}
-
-void NoStarveReadWriteMutex::acquireWrite() const {
- // if we can acquire the rwlock the easy way, we're done
- if (attemptWrite()) {
- return;
- }
-
- // failed to get the rwlock, do it the hard way:
- // locking the mutex and setting writerWaiting will cause all new readers to
- // block on the mutex rather than on the rwlock.
- mutex_.lock();
- writerWaiting_ = true;
- ReadWriteMutex::acquireWrite();
- writerWaiting_ = false;
- mutex_.unlock();
-}
}
}
} // apache::thrift::concurrency
diff --git a/lib/cpp/src/thrift/concurrency/Mutex.h b/lib/cpp/src/thrift/concurrency/Mutex.h
index 09b938e..27e386e 100644
--- a/lib/cpp/src/thrift/concurrency/Mutex.h
+++ b/lib/cpp/src/thrift/concurrency/Mutex.h
@@ -20,39 +20,13 @@
#ifndef _THRIFT_CONCURRENCY_MUTEX_H_
#define _THRIFT_CONCURRENCY_MUTEX_H_ 1
-#include <thrift/stdcxx.h>
+#include <memory>
#include <boost/noncopyable.hpp>
-#include <stdint.h>
namespace apache {
namespace thrift {
namespace concurrency {
-#ifndef THRIFT_NO_CONTENTION_PROFILING
-
-/**
- * Determines if the Thrift Mutex and ReadWriteMutex classes will attempt to
- * profile their blocking acquire methods. If this value is set to non-zero,
- * Thrift will attempt to invoke the callback once every profilingSampleRate
- * times. However, as the sampling is not synchronized the rate is not
- * guranateed, and could be subject to big bursts and swings. Please ensure
- * your sampling callback is as performant as your application requires.
- *
- * The callback will get called with the wait time taken to lock the mutex in
- * usec and a (void*) that uniquely identifies the Mutex (or ReadWriteMutex)
- * being locked.
- *
- * The enableMutexProfiling() function is unsynchronized; calling this function
- * while profiling is already enabled may result in race conditions. On
- * architectures where a pointer assignment is atomic, this is safe but there
- * is no guarantee threads will agree on a single callback within any
- * particular time period.
- */
-typedef void (*MutexWaitCallback)(const void* id, int64_t waitTimeMicros);
-void enableMutexProfiling(int32_t profilingSampleRate, MutexWaitCallback callback);
-
-#endif
-
/**
* NOTE: All mutex implementations throw an exception on failure. See each
* specific implementation to understand the exception type(s) used.
@@ -65,10 +39,8 @@
*/
class Mutex {
public:
- typedef void (*Initializer)(void*);
-
- Mutex(Initializer init = DEFAULT_INITIALIZER);
- virtual ~Mutex() {}
+ Mutex();
+ virtual ~Mutex() = default;
virtual void lock() const;
virtual bool trylock() const;
@@ -77,57 +49,11 @@
void* getUnderlyingImpl() const;
- // If you attempt to use one of these and it fails to link, it means
- // your version of pthreads does not support it - try another one.
- static void ADAPTIVE_INITIALIZER(void*);
- static void DEFAULT_INITIALIZER(void*);
- static void ERRORCHECK_INITIALIZER(void*);
- static void RECURSIVE_INITIALIZER(void*);
-
private:
class impl;
- stdcxx::shared_ptr<impl> impl_;
+ std::shared_ptr<impl> impl_;
};
-class ReadWriteMutex {
-public:
- ReadWriteMutex();
- virtual ~ReadWriteMutex() {}
-
- // these get the lock and block until it is done successfully
- virtual void acquireRead() const;
- virtual void acquireWrite() const;
-
- // these attempt to get the lock, returning false immediately if they fail
- virtual bool attemptRead() const;
- virtual bool attemptWrite() const;
-
- // this releases both read and write locks
- virtual void release() const;
-
-private:
- class impl;
- stdcxx::shared_ptr<impl> impl_;
-};
-
-/**
- * A ReadWriteMutex that guarantees writers will not be starved by readers:
- * When a writer attempts to acquire the mutex, all new readers will be
- * blocked from acquiring the mutex until the writer has acquired and
- * released it. In some operating systems, this may already be guaranteed
- * by a regular ReadWriteMutex.
- */
-class NoStarveReadWriteMutex : public ReadWriteMutex {
-public:
- NoStarveReadWriteMutex();
-
- virtual void acquireRead() const;
- virtual void acquireWrite() const;
-
-private:
- Mutex mutex_;
- mutable volatile bool writerWaiting_;
-};
class Guard : boost::noncopyable {
public:
@@ -136,11 +62,11 @@
value.lock();
} else if (timeout < 0) {
if (!value.trylock()) {
- mutex_ = NULL;
+ mutex_ = nullptr;
}
} else {
if (!value.timedlock(timeout)) {
- mutex_ = NULL;
+ mutex_ = nullptr;
}
}
}
@@ -150,38 +76,12 @@
}
}
- operator bool() const { return (mutex_ != NULL); }
+ operator bool() const { return (mutex_ != nullptr); }
private:
const Mutex* mutex_;
};
-// Can be used as second argument to RWGuard to make code more readable
-// as to whether we're doing acquireRead() or acquireWrite().
-enum RWGuardType { RW_READ = 0, RW_WRITE = 1 };
-
-class RWGuard : boost::noncopyable {
-public:
- RWGuard(const ReadWriteMutex& value, bool write = false) : rw_mutex_(value) {
- if (write) {
- rw_mutex_.acquireWrite();
- } else {
- rw_mutex_.acquireRead();
- }
- }
-
- RWGuard(const ReadWriteMutex& value, RWGuardType type) : rw_mutex_(value) {
- if (type == RW_WRITE) {
- rw_mutex_.acquireWrite();
- } else {
- rw_mutex_.acquireRead();
- }
- }
- ~RWGuard() { rw_mutex_.release(); }
-
-private:
- const ReadWriteMutex& rw_mutex_;
-};
}
}
} // apache::thrift::concurrency
diff --git a/lib/cpp/src/thrift/concurrency/PlatformThreadFactory.h b/lib/cpp/src/thrift/concurrency/PlatformThreadFactory.h
deleted file mode 100644
index 545b572..0000000
--- a/lib/cpp/src/thrift/concurrency/PlatformThreadFactory.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _THRIFT_CONCURRENCY_PLATFORMTHREADFACTORY_H_
-#define _THRIFT_CONCURRENCY_PLATFORMTHREADFACTORY_H_ 1
-
-// clang-format off
-#include <thrift/thrift-config.h>
-#if USE_BOOST_THREAD
-# include <thrift/concurrency/BoostThreadFactory.h>
-#elif USE_STD_THREAD
-# include <thrift/concurrency/StdThreadFactory.h>
-#else
-# include <thrift/concurrency/PosixThreadFactory.h>
-#endif
-// clang-format on
-
-namespace apache {
-namespace thrift {
-namespace concurrency {
-
-// clang-format off
-#if USE_BOOST_THREAD
- typedef BoostThreadFactory PlatformThreadFactory;
-#elif USE_STD_THREAD
- typedef StdThreadFactory PlatformThreadFactory;
-#else
- typedef PosixThreadFactory PlatformThreadFactory;
-#endif
-// clang-format on
-
-}
-}
-} // apache::thrift::concurrency
-
-#endif // #ifndef _THRIFT_CONCURRENCY_PLATFORMTHREADFACTORY_H_
diff --git a/lib/cpp/src/thrift/concurrency/PosixThreadFactory.cpp b/lib/cpp/src/thrift/concurrency/PosixThreadFactory.cpp
deleted file mode 100644
index 2e35446..0000000
--- a/lib/cpp/src/thrift/concurrency/PosixThreadFactory.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * 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.
- */
-
-#include <thrift/thrift-config.h>
-
-#include <thrift/concurrency/Exception.h>
-#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/PosixThreadFactory.h>
-
-#if GOOGLE_PERFTOOLS_REGISTER_THREAD
-#include <google/profiler.h>
-#endif
-
-#include <assert.h>
-#include <pthread.h>
-
-#include <iostream>
-
-#include <thrift/stdcxx.h>
-
-namespace apache {
-namespace thrift {
-namespace concurrency {
-
-/**
- * The POSIX thread class.
- *
- * @version $Id:$
- */
-class PthreadThread : public Thread {
-public:
- enum STATE { uninitialized, starting, started, stopping, stopped };
-
- static const int MB = 1024 * 1024;
-
- static void* threadMain(void* arg);
-
-private:
- pthread_t pthread_;
- Monitor monitor_; // guard to protect state_ and also notification
- STATE state_; // to protect proper thread start behavior
- int policy_;
- int priority_;
- int stackSize_;
- stdcxx::weak_ptr<PthreadThread> self_;
- bool detached_;
-
-public:
- PthreadThread(int policy,
- int priority,
- int stackSize,
- bool detached,
- stdcxx::shared_ptr<Runnable> runnable)
- :
-
-#ifndef _WIN32
- pthread_(0),
-#endif // _WIN32
- state_(uninitialized),
- policy_(policy),
- priority_(priority),
- stackSize_(stackSize),
- detached_(detached) {
-
- this->Thread::runnable(runnable);
- }
-
- ~PthreadThread() {
- /* Nothing references this thread, if is is not detached, do a join
- now, otherwise the thread-id and, possibly, other resources will
- be leaked. */
- if (!detached_) {
- try {
- join();
- } catch (...) {
- // We're really hosed.
- }
- }
- }
-
- STATE getState() const
- {
- Synchronized sync(monitor_);
- return state_;
- }
-
- void setState(STATE newState)
- {
- Synchronized sync(monitor_);
- state_ = newState;
-
- // unblock start() with the knowledge that the thread has actually
- // started running, which avoids a race in detached threads.
- if (newState == started) {
- monitor_.notify();
- }
- }
-
- void start() {
- if (getState() != uninitialized) {
- return;
- }
-
- pthread_attr_t thread_attr;
- if (pthread_attr_init(&thread_attr) != 0) {
- throw SystemResourceException("pthread_attr_init failed");
- }
-
- if (pthread_attr_setdetachstate(&thread_attr,
- detached_ ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE)
- != 0) {
- throw SystemResourceException("pthread_attr_setdetachstate failed");
- }
-
- // Set thread stack size
- if (pthread_attr_setstacksize(&thread_attr, MB * stackSize_) != 0) {
- throw SystemResourceException("pthread_attr_setstacksize failed");
- }
-
-// Set thread policy
-#ifdef _WIN32
- // WIN32 Pthread implementation doesn't seem to support sheduling policies other then
- // PosixThreadFactory::OTHER - runtime error
- policy_ = PosixThreadFactory::OTHER;
-#endif
-
-#if _POSIX_THREAD_PRIORITY_SCHEDULING > 0
- if (pthread_attr_setschedpolicy(&thread_attr, policy_) != 0) {
- throw SystemResourceException("pthread_attr_setschedpolicy failed");
- }
-#endif
-
- struct sched_param sched_param;
- sched_param.sched_priority = priority_;
-
- // Set thread priority
- if (pthread_attr_setschedparam(&thread_attr, &sched_param) != 0) {
- throw SystemResourceException("pthread_attr_setschedparam failed");
- }
-
- // Create reference
- stdcxx::shared_ptr<PthreadThread>* selfRef = new stdcxx::shared_ptr<PthreadThread>();
- *selfRef = self_.lock();
-
- setState(starting);
-
- Synchronized sync(monitor_);
-
- if (pthread_create(&pthread_, &thread_attr, threadMain, (void*)selfRef) != 0) {
- throw SystemResourceException("pthread_create failed");
- }
-
- // The caller may not choose to guarantee the scope of the Runnable
- // being used in the thread, so we must actually wait until the thread
- // starts before we return. If we do not wait, it would be possible
- // for the caller to start destructing the Runnable and the Thread,
- // and we would end up in a race. This was identified with valgrind.
- monitor_.wait();
- }
-
- void join() {
- if (!detached_ && getState() != uninitialized) {
- void* ignore;
- /* XXX
- If join fails it is most likely due to the fact
- that the last reference was the thread itself and cannot
- join. This results in leaked threads and will eventually
- cause the process to run out of thread resources.
- We're beyond the point of throwing an exception. Not clear how
- best to handle this. */
- int res = pthread_join(pthread_, &ignore);
- detached_ = (res == 0);
- if (res != 0) {
- GlobalOutput.printf("PthreadThread::join(): fail with code %d", res);
- }
- }
- }
-
- Thread::id_t getId() {
-
-#ifndef _WIN32
- return (Thread::id_t)pthread_;
-#else
- return (Thread::id_t)pthread_.p;
-#endif // _WIN32
- }
-
- stdcxx::shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
-
- void runnable(stdcxx::shared_ptr<Runnable> value) { Thread::runnable(value); }
-
- void weakRef(stdcxx::shared_ptr<PthreadThread> self) {
- assert(self.get() == this);
- self_ = stdcxx::weak_ptr<PthreadThread>(self);
- }
-};
-
-void* PthreadThread::threadMain(void* arg) {
- stdcxx::shared_ptr<PthreadThread> thread = *(stdcxx::shared_ptr<PthreadThread>*)arg;
- delete reinterpret_cast<stdcxx::shared_ptr<PthreadThread>*>(arg);
-
-#if GOOGLE_PERFTOOLS_REGISTER_THREAD
- ProfilerRegisterThread();
-#endif
-
- thread->setState(started);
-
- thread->runnable()->run();
-
- STATE _s = thread->getState();
- if (_s != stopping && _s != stopped) {
- thread->setState(stopping);
- }
-
- return (void*)0;
-}
-
-/**
- * Converts generic posix thread schedule policy enums into pthread
- * API values.
- */
-static int toPthreadPolicy(PosixThreadFactory::POLICY policy) {
- switch (policy) {
- case PosixThreadFactory::OTHER:
- return SCHED_OTHER;
- case PosixThreadFactory::FIFO:
- return SCHED_FIFO;
- case PosixThreadFactory::ROUND_ROBIN:
- return SCHED_RR;
- }
- return SCHED_OTHER;
-}
-
-/**
- * Converts relative thread priorities to absolute value based on posix
- * thread scheduler policy
- *
- * The idea is simply to divide up the priority range for the given policy
- * into the correpsonding relative priority level (lowest..highest) and
- * then pro-rate accordingly.
- */
-static int toPthreadPriority(PosixThreadFactory::POLICY policy, PosixThreadFactory::PRIORITY priority) {
- int pthread_policy = toPthreadPolicy(policy);
- int min_priority = 0;
- int max_priority = 0;
-#ifdef HAVE_SCHED_GET_PRIORITY_MIN
- min_priority = sched_get_priority_min(pthread_policy);
-#endif
-#ifdef HAVE_SCHED_GET_PRIORITY_MAX
- max_priority = sched_get_priority_max(pthread_policy);
-#endif
- int quanta = (PosixThreadFactory::HIGHEST - PosixThreadFactory::LOWEST) + 1;
- float stepsperquanta = (float)(max_priority - min_priority) / quanta;
-
- if (priority <= PosixThreadFactory::HIGHEST) {
- return (int)(min_priority + stepsperquanta * priority);
- } else {
- // should never get here for priority increments.
- assert(false);
- return (int)(min_priority + stepsperquanta * PosixThreadFactory::NORMAL);
- }
-}
-
-PosixThreadFactory::PosixThreadFactory(POLICY policy,
- PRIORITY priority,
- int stackSize,
- bool detached)
- : ThreadFactory(detached),
- policy_(policy),
- priority_(priority),
- stackSize_(stackSize) {
-}
-
-PosixThreadFactory::PosixThreadFactory(bool detached)
- : ThreadFactory(detached),
- policy_(ROUND_ROBIN),
- priority_(NORMAL),
- stackSize_(1) {
-}
-
-stdcxx::shared_ptr<Thread> PosixThreadFactory::newThread(stdcxx::shared_ptr<Runnable> runnable) const {
- stdcxx::shared_ptr<PthreadThread> result
- = stdcxx::shared_ptr<PthreadThread>(new PthreadThread(toPthreadPolicy(policy_),
- toPthreadPriority(policy_, priority_),
- stackSize_,
- isDetached(),
- runnable));
- result->weakRef(result);
- runnable->thread(result);
- return result;
-}
-
-int PosixThreadFactory::getStackSize() const {
- return stackSize_;
-}
-
-void PosixThreadFactory::setStackSize(int value) {
- stackSize_ = value;
-}
-
-PosixThreadFactory::PRIORITY PosixThreadFactory::getPriority() const {
- return priority_;
-}
-
-void PosixThreadFactory::setPriority(PRIORITY value) {
- priority_ = value;
-}
-
-Thread::id_t PosixThreadFactory::getCurrentThreadId() const {
-#ifndef _WIN32
- return (Thread::id_t)pthread_self();
-#else
- return (Thread::id_t)pthread_self().p;
-#endif // _WIN32
-}
-
-}
-}
-} // apache::thrift::concurrency
diff --git a/lib/cpp/src/thrift/concurrency/PosixThreadFactory.h b/lib/cpp/src/thrift/concurrency/PosixThreadFactory.h
deleted file mode 100644
index 5e04d01..0000000
--- a/lib/cpp/src/thrift/concurrency/PosixThreadFactory.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _THRIFT_CONCURRENCY_POSIXTHREADFACTORY_H_
-#define _THRIFT_CONCURRENCY_POSIXTHREADFACTORY_H_ 1
-
-#include <thrift/concurrency/Thread.h>
-
-#include <thrift/stdcxx.h>
-
-namespace apache {
-namespace thrift {
-namespace concurrency {
-
-/**
- * A thread factory to create posix threads
- *
- * @version $Id:$
- */
-class PosixThreadFactory : public ThreadFactory {
-
-public:
- /**
- * POSIX Thread scheduler policies
- */
- enum POLICY { OTHER, FIFO, ROUND_ROBIN };
-
- /**
- * POSIX Thread scheduler relative priorities,
- *
- * Absolute priority is determined by scheduler policy and OS. This
- * enumeration specifies relative priorities such that one can specify a
- * priority within a giving scheduler policy without knowing the absolute
- * value of the priority.
- */
- enum PRIORITY {
- LOWEST = 0,
- LOWER = 1,
- LOW = 2,
- NORMAL = 3,
- HIGH = 4,
- HIGHER = 5,
- HIGHEST = 6,
- INCREMENT = 7,
- DECREMENT = 8
- };
-
- /**
- * Posix thread (pthread) factory. All threads created by a factory are reference-counted
- * via stdcxx::shared_ptr. The factory guarantees that threads and the Runnable tasks
- * they host will be properly cleaned up once the last strong reference to both is
- * given up.
- *
- * Threads are created with the specified policy, priority, stack-size and detachable-mode
- * detached means the thread is free-running and will release all system resources the
- * when it completes. A detachable thread is not joinable. The join method
- * of a detachable thread will return immediately with no error.
- *
- * By default threads are not joinable.
- */
- PosixThreadFactory(POLICY policy = ROUND_ROBIN,
- PRIORITY priority = NORMAL,
- int stackSize = 1,
- bool detached = true);
-
- /**
- * Provide a constructor compatible with the other factories
- * The default policy is POLICY::ROUND_ROBIN.
- * The default priority is PRIORITY::NORMAL.
- * The default stackSize is 1.
- */
- PosixThreadFactory(bool detached);
-
- // From ThreadFactory;
- stdcxx::shared_ptr<Thread> newThread(stdcxx::shared_ptr<Runnable> runnable) const;
-
- // From ThreadFactory;
- Thread::id_t getCurrentThreadId() const;
-
- /**
- * Gets stack size for newly created threads
- *
- * @return int size in megabytes
- */
- virtual int getStackSize() const;
-
- /**
- * Sets stack size for newly created threads
- *
- * @param value size in megabytes
- */
- virtual void setStackSize(int value);
-
- /**
- * Gets priority relative to current policy
- */
- virtual PRIORITY getPriority() const;
-
- /**
- * Sets priority relative to current policy
- */
- virtual void setPriority(PRIORITY priority);
-
-private:
- POLICY policy_;
- PRIORITY priority_;
- int stackSize_;
-};
-}
-}
-} // apache::thrift::concurrency
-
-#endif // #ifndef _THRIFT_CONCURRENCY_POSIXTHREADFACTORY_H_
diff --git a/lib/cpp/src/thrift/concurrency/StdMonitor.cpp b/lib/cpp/src/thrift/concurrency/StdMonitor.cpp
deleted file mode 100644
index 7b3b209..0000000
--- a/lib/cpp/src/thrift/concurrency/StdMonitor.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * 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.
- */
-
-#include <thrift/thrift-config.h>
-
-#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/Exception.h>
-#include <thrift/concurrency/Util.h>
-#include <thrift/transport/PlatformSocket.h>
-#include <assert.h>
-
-#include <condition_variable>
-#include <chrono>
-#include <thread>
-#include <mutex>
-
-namespace apache {
-namespace thrift {
-namespace concurrency {
-
-/**
- * Monitor implementation using the std thread library
- *
- * @version $Id:$
- */
-class Monitor::Impl {
-
-public:
- Impl() : ownedMutex_(new Mutex()), conditionVariable_(), mutex_(NULL) { init(ownedMutex_.get()); }
-
- Impl(Mutex* mutex) : ownedMutex_(), conditionVariable_(), mutex_(NULL) { init(mutex); }
-
- Impl(Monitor* monitor) : ownedMutex_(), conditionVariable_(), mutex_(NULL) {
- init(&(monitor->mutex()));
- }
-
- Mutex& mutex() { return *mutex_; }
- void lock() { mutex_->lock(); }
- void unlock() { mutex_->unlock(); }
-
- /**
- * Exception-throwing version of waitForTimeRelative(), called simply
- * wait(int64) for historical reasons. Timeout is in milliseconds.
- *
- * If the condition occurs, this function returns cleanly; on timeout or
- * error an exception is thrown.
- */
- void wait(int64_t timeout_ms) {
- int result = waitForTimeRelative(timeout_ms);
- if (result == THRIFT_ETIMEDOUT) {
- throw TimedOutException();
- } else if (result != 0) {
- throw TException("Monitor::wait() failed");
- }
- }
-
- /**
- * Waits until the specified timeout in milliseconds for the condition to
- * occur, or waits forever if timeout_ms == 0.
- *
- * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
- */
- int waitForTimeRelative(int64_t timeout_ms) {
- if (timeout_ms == 0LL) {
- return waitForever();
- }
-
- assert(mutex_);
- std::timed_mutex* mutexImpl = static_cast<std::timed_mutex*>(mutex_->getUnderlyingImpl());
- assert(mutexImpl);
-
- std::unique_lock<std::timed_mutex> lock(*mutexImpl, std::adopt_lock);
- bool timedout = (conditionVariable_.wait_for(lock, std::chrono::milliseconds(timeout_ms))
- == std::cv_status::timeout);
- lock.release();
- return (timedout ? THRIFT_ETIMEDOUT : 0);
- }
-
- /**
- * Waits until the absolute time specified using struct THRIFT_TIMESPEC.
- * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
- */
- int waitForTime(const THRIFT_TIMESPEC* abstime) {
- struct timeval temp;
- temp.tv_sec = static_cast<long>(abstime->tv_sec);
- temp.tv_usec = static_cast<long>(abstime->tv_nsec) / 1000;
- return waitForTime(&temp);
- }
-
- /**
- * Waits until the absolute time specified using struct timeval.
- * Returns 0 if condition occurs, THRIFT_ETIMEDOUT on timeout, or an error code.
- */
- int waitForTime(const struct timeval* abstime) {
- assert(mutex_);
- std::timed_mutex* mutexImpl = static_cast<std::timed_mutex*>(mutex_->getUnderlyingImpl());
- assert(mutexImpl);
-
- struct timeval currenttime;
- Util::toTimeval(currenttime, Util::currentTime());
-
- long tv_sec = static_cast<long>(abstime->tv_sec - currenttime.tv_sec);
- long tv_usec = static_cast<long>(abstime->tv_usec - currenttime.tv_usec);
- if (tv_sec < 0)
- tv_sec = 0;
- if (tv_usec < 0)
- tv_usec = 0;
-
- std::unique_lock<std::timed_mutex> lock(*mutexImpl, std::adopt_lock);
- bool timedout = (conditionVariable_.wait_for(lock,
- std::chrono::seconds(tv_sec)
- + std::chrono::microseconds(tv_usec))
- == std::cv_status::timeout);
- lock.release();
- return (timedout ? THRIFT_ETIMEDOUT : 0);
- }
-
- /**
- * Waits forever until the condition occurs.
- * Returns 0 if condition occurs, or an error code otherwise.
- */
- int waitForever() {
- assert(mutex_);
- std::timed_mutex* mutexImpl = static_cast<std::timed_mutex*>(mutex_->getUnderlyingImpl());
- assert(mutexImpl);
-
- std::unique_lock<std::timed_mutex> lock(*mutexImpl, std::adopt_lock);
- conditionVariable_.wait(lock);
- lock.release();
- return 0;
- }
-
- void notify() { conditionVariable_.notify_one(); }
-
- void notifyAll() { conditionVariable_.notify_all(); }
-
-private:
- void init(Mutex* mutex) { mutex_ = mutex; }
-
- const std::unique_ptr<Mutex> ownedMutex_;
- std::condition_variable_any conditionVariable_;
- Mutex* mutex_;
-};
-
-Monitor::Monitor() : impl_(new Monitor::Impl()) {
-}
-Monitor::Monitor(Mutex* mutex) : impl_(new Monitor::Impl(mutex)) {
-}
-Monitor::Monitor(Monitor* monitor) : impl_(new Monitor::Impl(monitor)) {
-}
-
-Monitor::~Monitor() {
- delete impl_;
-}
-
-Mutex& Monitor::mutex() const {
- return const_cast<Monitor::Impl*>(impl_)->mutex();
-}
-
-void Monitor::lock() const {
- const_cast<Monitor::Impl*>(impl_)->lock();
-}
-
-void Monitor::unlock() const {
- const_cast<Monitor::Impl*>(impl_)->unlock();
-}
-
-void Monitor::wait(int64_t timeout) const {
- const_cast<Monitor::Impl*>(impl_)->wait(timeout);
-}
-
-int Monitor::waitForTime(const THRIFT_TIMESPEC* abstime) const {
- return const_cast<Monitor::Impl*>(impl_)->waitForTime(abstime);
-}
-
-int Monitor::waitForTime(const timeval* abstime) const {
- return const_cast<Monitor::Impl*>(impl_)->waitForTime(abstime);
-}
-
-int Monitor::waitForTimeRelative(int64_t timeout_ms) const {
- return const_cast<Monitor::Impl*>(impl_)->waitForTimeRelative(timeout_ms);
-}
-
-int Monitor::waitForever() const {
- return const_cast<Monitor::Impl*>(impl_)->waitForever();
-}
-
-void Monitor::notify() const {
- const_cast<Monitor::Impl*>(impl_)->notify();
-}
-
-void Monitor::notifyAll() const {
- const_cast<Monitor::Impl*>(impl_)->notifyAll();
-}
-}
-}
-} // apache::thrift::concurrency
diff --git a/lib/cpp/src/thrift/concurrency/StdMutex.cpp b/lib/cpp/src/thrift/concurrency/StdMutex.cpp
deleted file mode 100644
index e0f79fa..0000000
--- a/lib/cpp/src/thrift/concurrency/StdMutex.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.
- */
-
-#include <thrift/thrift-config.h>
-
-#include <thrift/concurrency/Mutex.h>
-#include <thrift/concurrency/Util.h>
-
-#include <cassert>
-#include <chrono>
-#include <mutex>
-
-namespace apache {
-namespace thrift {
-namespace concurrency {
-
-/**
- * Implementation of Mutex class using C++11 std::timed_mutex
- *
- * Methods throw std::system_error on error.
- *
- * @version $Id:$
- */
-class Mutex::impl : public std::timed_mutex {};
-
-Mutex::Mutex(Initializer init) : impl_(new Mutex::impl()) {
- ((void)init);
-}
-
-void* Mutex::getUnderlyingImpl() const {
- return impl_.get();
-}
-
-void Mutex::lock() const {
- impl_->lock();
-}
-
-bool Mutex::trylock() const {
- return impl_->try_lock();
-}
-
-bool Mutex::timedlock(int64_t ms) const {
- return impl_->try_lock_for(std::chrono::milliseconds(ms));
-}
-
-void Mutex::unlock() const {
- impl_->unlock();
-}
-
-void Mutex::DEFAULT_INITIALIZER(void* arg) {
- ((void)arg);
-}
-}
-}
-} // apache::thrift::concurrency
diff --git a/lib/cpp/src/thrift/concurrency/StdThreadFactory.cpp b/lib/cpp/src/thrift/concurrency/StdThreadFactory.cpp
deleted file mode 100644
index da0c5e3..0000000
--- a/lib/cpp/src/thrift/concurrency/StdThreadFactory.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.
- */
-
-#include <thrift/thrift-config.h>
-
-#if USE_STD_THREAD
-
-#include <thrift/concurrency/Exception.h>
-#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/StdThreadFactory.h>
-#include <thrift/stdcxx.h>
-
-#include <cassert>
-#include <thread>
-
-namespace apache {
-namespace thrift {
-namespace concurrency {
-
-/**
- * The C++11 thread class.
- *
- * Note that we use boost shared_ptr rather than std shared_ptrs here
- * because the Thread/Runnable classes use those and we don't want to
- * mix them.
- *
- * @version $Id:$
- */
-class StdThread : public Thread, public stdcxx::enable_shared_from_this<StdThread> {
-public:
- enum STATE { uninitialized, starting, started, stopping, stopped };
-
- static void threadMain(stdcxx::shared_ptr<StdThread> thread);
-
-private:
- std::unique_ptr<std::thread> thread_;
- Monitor monitor_;
- STATE state_;
- bool detached_;
-
-public:
- StdThread(bool detached, stdcxx::shared_ptr<Runnable> runnable)
- : state_(uninitialized), detached_(detached) {
- this->Thread::runnable(runnable);
- }
-
- ~StdThread() {
- if (!detached_ && thread_->joinable()) {
- try {
- join();
- } catch (...) {
- // We're really hosed.
- }
- }
- }
-
- STATE getState() const
- {
- Synchronized sync(monitor_);
- return state_;
- }
-
- void setState(STATE newState)
- {
- Synchronized sync(monitor_);
- state_ = newState;
-
- // unblock start() with the knowledge that the thread has actually
- // started running, which avoids a race in detached threads.
- if (newState == started) {
- monitor_.notify();
- }
- }
-
- void start() {
- if (getState() != uninitialized) {
- return;
- }
-
- stdcxx::shared_ptr<StdThread> selfRef = shared_from_this();
- setState(starting);
-
- Synchronized sync(monitor_);
- thread_ = std::unique_ptr<std::thread>(new std::thread(threadMain, selfRef));
-
- if (detached_)
- thread_->detach();
-
- // Wait for the thread to start and get far enough to grab everything
- // that it needs from the calling context, thus absolving the caller
- // from being required to hold on to runnable indefinitely.
- monitor_.wait();
- }
-
- void join() {
- if (!detached_ && state_ != uninitialized) {
- thread_->join();
- }
- }
-
- Thread::id_t getId() { return thread_.get() ? thread_->get_id() : std::thread::id(); }
-
- stdcxx::shared_ptr<Runnable> runnable() const { return Thread::runnable(); }
-
- void runnable(stdcxx::shared_ptr<Runnable> value) { Thread::runnable(value); }
-};
-
-void StdThread::threadMain(stdcxx::shared_ptr<StdThread> thread) {
-#if GOOGLE_PERFTOOLS_REGISTER_THREAD
- ProfilerRegisterThread();
-#endif
-
- thread->setState(started);
- thread->runnable()->run();
-
- if (thread->getState() != stopping && thread->getState() != stopped) {
- thread->setState(stopping);
- }
-}
-
-StdThreadFactory::StdThreadFactory(bool detached) : ThreadFactory(detached) {
-}
-
-stdcxx::shared_ptr<Thread> StdThreadFactory::newThread(stdcxx::shared_ptr<Runnable> runnable) const {
- stdcxx::shared_ptr<StdThread> result = stdcxx::shared_ptr<StdThread>(new StdThread(isDetached(), runnable));
- runnable->thread(result);
- return result;
-}
-
-Thread::id_t StdThreadFactory::getCurrentThreadId() const {
- return std::this_thread::get_id();
-}
-}
-}
-} // apache::thrift::concurrency
-
-#endif // USE_STD_THREAD
diff --git a/lib/cpp/src/thrift/concurrency/StdThreadFactory.h b/lib/cpp/src/thrift/concurrency/StdThreadFactory.h
deleted file mode 100644
index 8e116b6..0000000
--- a/lib/cpp/src/thrift/concurrency/StdThreadFactory.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _THRIFT_CONCURRENCY_STDTHREADFACTORY_H_
-#define _THRIFT_CONCURRENCY_STDTHREADFACTORY_H_ 1
-
-#include <thrift/concurrency/Thread.h>
-
-#include <thrift/stdcxx.h>
-
-namespace apache {
-namespace thrift {
-namespace concurrency {
-
-/**
- * A thread factory to create std::threads.
- *
- * @version $Id:$
- */
-class StdThreadFactory : public ThreadFactory {
-
-public:
- /**
- * Std thread factory. All threads created by a factory are reference-counted
- * via stdcxx::shared_ptr. The factory guarantees that threads and the Runnable tasks
- * they host will be properly cleaned up once the last strong reference
- * to both is given up.
- *
- * By default threads are not joinable.
- */
-
- StdThreadFactory(bool detached = true);
-
- // From ThreadFactory;
- stdcxx::shared_ptr<Thread> newThread(stdcxx::shared_ptr<Runnable> runnable) const;
-
- // From ThreadFactory;
- Thread::id_t getCurrentThreadId() const;
-};
-
-}
-}
-} // apache::thrift::concurrency
-
-#endif // #ifndef _THRIFT_CONCURRENCY_STDTHREADFACTORY_H_
diff --git a/compiler/cpp/src/thrift/plugin/plugin_output.h b/lib/cpp/src/thrift/concurrency/Thread.cpp
similarity index 68%
rename from compiler/cpp/src/thrift/plugin/plugin_output.h
rename to lib/cpp/src/thrift/concurrency/Thread.cpp
index eab2d1b..a2bb127 100644
--- a/compiler/cpp/src/thrift/plugin/plugin_output.h
+++ b/lib/cpp/src/thrift/concurrency/Thread.cpp
@@ -17,22 +17,21 @@
* under the License.
*/
-#ifndef T_PLUGIN_PLUGIN_OUTPUT_H
-#define T_PLUGIN_PLUGIN_OUTPUT_H
+#include <thrift/concurrency/Thread.h>
-#include <string>
+namespace apache {
+namespace thrift {
+namespace concurrency {
-class t_program;
+void Thread::threadMain(std::shared_ptr<Thread> thread) {
+ thread->setState(started);
+ thread->runnable()->run();
-namespace plugin_output {
-
-enum PluginDelegateResult {
- PLUGIN_NOT_FOUND,
- PLUGIN_FAILURE,
- PLUGIN_SUCCEESS,
-};
-
-PluginDelegateResult delegateToPlugin(t_program* program, const std::string& options);
+ if (thread->getState() != stopping && thread->getState() != stopped) {
+ thread->setState(stopping);
+ }
}
-#endif
+}
+}
+} // apache::thrift::concurrency
diff --git a/lib/cpp/src/thrift/concurrency/Thread.h b/lib/cpp/src/thrift/concurrency/Thread.h
index 788623b..e803a82 100644
--- a/lib/cpp/src/thrift/concurrency/Thread.h
+++ b/lib/cpp/src/thrift/concurrency/Thread.h
@@ -20,20 +20,10 @@
#ifndef _THRIFT_CONCURRENCY_THREAD_H_
#define _THRIFT_CONCURRENCY_THREAD_H_ 1
-#include <stdint.h>
-#include <thrift/stdcxx.h>
-
-#include <thrift/thrift-config.h>
-
-#if USE_BOOST_THREAD
-#include <boost/thread.hpp>
-#elif USE_STD_THREAD
+#include <memory>
#include <thread>
-#else
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-#endif
+
+#include <thrift/concurrency/Monitor.h>
namespace apache {
namespace thrift {
@@ -49,23 +39,23 @@
class Runnable {
public:
- virtual ~Runnable(){};
+ virtual ~Runnable() = default;
virtual void run() = 0;
/**
* Gets the thread object that is hosting this runnable object - can return
* an empty boost::shared pointer if no references remain on that thread object
*/
- virtual stdcxx::shared_ptr<Thread> thread() { return thread_.lock(); }
+ virtual std::shared_ptr<Thread> thread() { return thread_.lock(); }
/**
* Sets the thread that is executing this object. This is only meant for
* use by concrete implementations of Thread.
*/
- virtual void thread(stdcxx::shared_ptr<Thread> value) { thread_ = value; }
+ virtual void thread(std::shared_ptr<Thread> value) { thread_ = value; }
private:
- stdcxx::weak_ptr<Thread> thread_;
+ std::weak_ptr<Thread> thread_;
};
/**
@@ -77,99 +67,106 @@
*
* @see apache::thrift::concurrency::ThreadFactory)
*/
-class Thread {
+class Thread final : public std::enable_shared_from_this<Thread> {
public:
-#if USE_BOOST_THREAD
- typedef boost::thread::id id_t;
-
- static inline bool is_current(id_t t) { return t == boost::this_thread::get_id(); }
- static inline id_t get_current() { return boost::this_thread::get_id(); }
-#elif USE_STD_THREAD
typedef std::thread::id id_t;
+ enum STATE { uninitialized, starting, started, stopping, stopped };
+
+ static void threadMain(std::shared_ptr<Thread> thread);
+
static inline bool is_current(id_t t) { return t == std::this_thread::get_id(); }
static inline id_t get_current() { return std::this_thread::get_id(); }
-#else
- typedef pthread_t id_t;
- static inline bool is_current(id_t t) { return pthread_equal(pthread_self(), t); }
- static inline id_t get_current() { return pthread_self(); }
-#endif
+ Thread(bool detached, std::shared_ptr<Runnable> runnable)
+ : state_(uninitialized), detached_(detached) {
+ this->_runnable = runnable;
+ }
- virtual ~Thread(){};
+ ~Thread() {
+ if (!detached_ && thread_->joinable()) {
+ try {
+ join();
+ } catch (...) {
+ // We're really hosed.
+ }
+ }
+ }
+
+ STATE getState() const
+ {
+ Synchronized sync(monitor_);
+ return state_;
+ }
+
+ void setState(STATE newState)
+ {
+ Synchronized sync(monitor_);
+ state_ = newState;
+
+ // unblock start() with the knowledge that the thread has actually
+ // started running, which avoids a race in detached threads.
+ if (newState == started) {
+ monitor_.notify();
+ }
+ }
/**
* Starts the thread. Does platform specific thread creation and
* configuration then invokes the run method of the Runnable object bound
* to this thread.
*/
- virtual void start() = 0;
+ void start() {
+ if (getState() != uninitialized) {
+ return;
+ }
+
+ std::shared_ptr<Thread> selfRef = shared_from_this();
+ setState(starting);
+
+ Synchronized sync(monitor_);
+ thread_ = std::unique_ptr<std::thread>(new std::thread(threadMain, selfRef));
+
+ if (detached_)
+ thread_->detach();
+
+ // Wait for the thread to start and get far enough to grab everything
+ // that it needs from the calling context, thus absolving the caller
+ // from being required to hold on to runnable indefinitely.
+ monitor_.wait();
+ }
/**
* Join this thread. If this thread is joinable, the calling thread blocks
* until this thread completes. If the target thread is not joinable, then
* nothing happens.
*/
- virtual void join() = 0;
+ void join() {
+ if (!detached_ && state_ != uninitialized) {
+ thread_->join();
+ }
+ }
/**
* Gets the thread's platform-specific ID
*/
- virtual id_t getId() = 0;
+ Thread::id_t getId() const { return thread_.get() ? thread_->get_id() : std::thread::id(); }
/**
* Gets the runnable object this thread is hosting
*/
- virtual stdcxx::shared_ptr<Runnable> runnable() const { return _runnable; }
-
-protected:
- virtual void runnable(stdcxx::shared_ptr<Runnable> value) { _runnable = value; }
+ std::shared_ptr<Runnable> runnable() const { return _runnable; }
private:
- stdcxx::shared_ptr<Runnable> _runnable;
-};
-
-/**
- * Factory to create platform-specific thread object and bind them to Runnable
- * object for execution
- */
-class ThreadFactory {
-protected:
- ThreadFactory(bool detached) : detached_(detached) { }
-
-public:
- virtual ~ThreadFactory() { }
-
- /**
- * Gets current detached mode
- */
- bool isDetached() const { return detached_; }
-
- /**
- * Sets the detached disposition of newly created threads.
- */
- void setDetached(bool detached) { detached_ = detached; }
-
- /**
- * Create a new thread.
- */
- virtual stdcxx::shared_ptr<Thread> newThread(stdcxx::shared_ptr<Runnable> runnable) const = 0;
-
- /**
- * Gets the current thread id or unknown_thread_id if the current thread is not a thrift thread
- */
- virtual Thread::id_t getCurrentThreadId() const = 0;
-
- /**
- * For code readability define the unknown/undefined thread id
- */
- static const Thread::id_t unknown_thread_id;
-
-private:
+ std::shared_ptr<Runnable> _runnable;
+ std::unique_ptr<std::thread> thread_;
+ Monitor monitor_;
+ STATE state_;
bool detached_;
};
+
}
}
} // apache::thrift::concurrency
diff --git a/lib/cpp/src/thrift/concurrency/Util.cpp b/lib/cpp/src/thrift/concurrency/ThreadFactory.cpp
similarity index 71%
rename from lib/cpp/src/thrift/concurrency/Util.cpp
rename to lib/cpp/src/thrift/concurrency/ThreadFactory.cpp
index dd6d19f..becb3b2 100644
--- a/lib/cpp/src/thrift/concurrency/Util.cpp
+++ b/lib/cpp/src/thrift/concurrency/ThreadFactory.cpp
@@ -19,26 +19,22 @@
#include <thrift/thrift-config.h>
-#include <thrift/Thrift.h>
-#include <thrift/concurrency/Util.h>
-
-#if defined(HAVE_SYS_TIME_H)
-#include <sys/time.h>
-#endif
+#include <thrift/concurrency/ThreadFactory.h>
+#include <memory>
namespace apache {
namespace thrift {
namespace concurrency {
-int64_t Util::currentTimeTicks(int64_t ticksPerSec) {
- int64_t result;
- struct timeval now;
- int ret = THRIFT_GETTIMEOFDAY(&now, NULL);
- assert(ret == 0);
- THRIFT_UNUSED_VARIABLE(ret); // squelching "unused variable" warning
- toTicks(result, now, ticksPerSec);
+std::shared_ptr<Thread> ThreadFactory::newThread(std::shared_ptr<Runnable> runnable) const {
+ std::shared_ptr<Thread> result = std::make_shared<Thread>(isDetached(), runnable);
+ runnable->thread(result);
return result;
}
+
+Thread::id_t ThreadFactory::getCurrentThreadId() const {
+ return std::this_thread::get_id();
+}
}
}
} // apache::thrift::concurrency
diff --git a/lib/cpp/src/thrift/concurrency/ThreadFactory.h b/lib/cpp/src/thrift/concurrency/ThreadFactory.h
new file mode 100644
index 0000000..a1547a6
--- /dev/null
+++ b/lib/cpp/src/thrift/concurrency/ThreadFactory.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+#ifndef _THRIFT_CONCURRENCY_THREADFACTORY_H_
+#define _THRIFT_CONCURRENCY_THREADFACTORY_H_ 1
+
+#include <thrift/concurrency/Thread.h>
+
+#include <memory>
+namespace apache {
+namespace thrift {
+namespace concurrency {
+
+/**
+ * Factory to create thread object and bind them to Runnable
+ * object for execution
+ */
+class ThreadFactory final {
+public:
+ /**
+ * All threads created by a factory are reference-counted
+ * via std::shared_ptr. The factory guarantees that threads and the Runnable tasks
+ * they host will be properly cleaned up once the last strong reference
+ * to both is given up.
+ *
+ * By default threads are not joinable.
+ */
+ ThreadFactory(bool detached = true) : detached_(detached) { }
+
+ ~ThreadFactory() = default;
+
+ /**
+ * Gets current detached mode
+ */
+ bool isDetached() const { return detached_; }
+
+ /**
+ * Sets the detached disposition of newly created threads.
+ */
+ void setDetached(bool detached) { detached_ = detached; }
+
+ /**
+ * Create a new thread.
+ */
+ std::shared_ptr<Thread> newThread(std::shared_ptr<Runnable> runnable) const;
+
+ /**
+ * Gets the current thread id or unknown_thread_id if the current thread is not a thrift thread
+ */
+ Thread::id_t getCurrentThreadId() const;
+
+private:
+ bool detached_;
+};
+
+}
+}
+} // apache::thrift::concurrency
+
+#endif // #ifndef _THRIFT_CONCURRENCY_THREADFACTORY_H_
diff --git a/lib/cpp/src/thrift/concurrency/ThreadManager.cpp b/lib/cpp/src/thrift/concurrency/ThreadManager.cpp
index 2e27b7f..25b838a 100644
--- a/lib/cpp/src/thrift/concurrency/ThreadManager.cpp
+++ b/lib/cpp/src/thrift/concurrency/ThreadManager.cpp
@@ -22,9 +22,8 @@
#include <thrift/concurrency/ThreadManager.h>
#include <thrift/concurrency/Exception.h>
#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/Util.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <stdexcept>
#include <deque>
@@ -34,8 +33,9 @@
namespace thrift {
namespace concurrency {
-using stdcxx::shared_ptr;
-using stdcxx::dynamic_pointer_cast;
+using std::shared_ptr;
+using std::unique_ptr;
+using std::dynamic_pointer_cast;
/**
* ThreadManager class
@@ -64,19 +64,19 @@
maxMonitor_(&mutex_),
workerMonitor_(&mutex_) {}
- ~Impl() { stop(); }
+ ~Impl() override { stop(); }
- void start();
- void stop();
+ void start() override;
+ void stop() override;
- ThreadManager::STATE state() const { return state_; }
+ ThreadManager::STATE state() const override { return state_; }
- shared_ptr<ThreadFactory> threadFactory() const {
+ shared_ptr<ThreadFactory> threadFactory() const override {
Guard g(mutex_);
return threadFactory_;
}
- void threadFactory(shared_ptr<ThreadFactory> value) {
+ void threadFactory(shared_ptr<ThreadFactory> value) override {
Guard g(mutex_);
if (threadFactory_ && threadFactory_->isDetached() != value->isDetached()) {
throw InvalidArgumentException();
@@ -84,33 +84,33 @@
threadFactory_ = value;
}
- void addWorker(size_t value);
+ void addWorker(size_t value) override;
- void removeWorker(size_t value);
+ void removeWorker(size_t value) override;
- size_t idleWorkerCount() const { return idleCount_; }
+ size_t idleWorkerCount() const override { return idleCount_; }
- size_t workerCount() const {
+ size_t workerCount() const override {
Guard g(mutex_);
return workerCount_;
}
- size_t pendingTaskCount() const {
+ size_t pendingTaskCount() const override {
Guard g(mutex_);
return tasks_.size();
}
- size_t totalTaskCount() const {
+ size_t totalTaskCount() const override {
Guard g(mutex_);
return tasks_.size() + workerCount_ - idleCount_;
}
- size_t pendingTaskCountMax() const {
+ size_t pendingTaskCountMax() const override {
Guard g(mutex_);
return pendingTaskCountMax_;
}
- size_t expiredTaskCount() {
+ size_t expiredTaskCount() const override {
Guard g(mutex_);
return expiredCount_;
}
@@ -120,17 +120,17 @@
pendingTaskCountMax_ = value;
}
- void add(shared_ptr<Runnable> value, int64_t timeout, int64_t expiration);
+ void add(shared_ptr<Runnable> value, int64_t timeout, int64_t expiration) override;
- void remove(shared_ptr<Runnable> task);
+ void remove(shared_ptr<Runnable> task) override;
- shared_ptr<Runnable> removeNextPending();
+ shared_ptr<Runnable> removeNextPending() override;
- void removeExpiredTasks() {
+ void removeExpiredTasks() override {
removeExpired(false);
}
- void setExpireCallback(ExpireCallback expireCallback);
+ void setExpireCallback(ExpireCallback expireCallback) override;
private:
/**
@@ -180,14 +180,17 @@
public:
enum STATE { WAITING, EXECUTING, TIMEDOUT, COMPLETE };
- Task(shared_ptr<Runnable> runnable, int64_t expiration = 0LL)
+ Task(shared_ptr<Runnable> runnable, uint64_t expiration = 0ULL)
: runnable_(runnable),
- state_(WAITING),
- expireTime_(expiration != 0LL ? Util::currentTime() + expiration : 0LL) {}
+ state_(WAITING) {
+ if (expiration != 0ULL) {
+ expireTime_.reset(new std::chrono::steady_clock::time_point(std::chrono::steady_clock::now() + std::chrono::milliseconds(expiration)));
+ }
+ }
- ~Task() {}
+ ~Task() override = default;
- void run() {
+ void run() override {
if (state_ == EXECUTING) {
runnable_->run();
state_ = COMPLETE;
@@ -196,13 +199,13 @@
shared_ptr<Runnable> getRunnable() { return runnable_; }
- int64_t getExpireTime() const { return expireTime_; }
+ const unique_ptr<std::chrono::steady_clock::time_point> & getExpireTime() const { return expireTime_; }
private:
shared_ptr<Runnable> runnable_;
friend class ThreadManager::Worker;
STATE state_;
- int64_t expireTime_;
+ unique_ptr<std::chrono::steady_clock::time_point> expireTime_;
};
class ThreadManager::Worker : public Runnable {
@@ -211,7 +214,7 @@
public:
Worker(ThreadManager::Impl* manager) : manager_(manager), state_(UNINITIALIZED) {}
- ~Worker() {}
+ ~Worker() override = default;
private:
bool isActive() const {
@@ -226,7 +229,7 @@
* As long as worker thread is running, pull tasks off the task queue and
* execute.
*/
- void run() {
+ void run() override {
Guard g(manager_->mutex_);
/**
@@ -280,7 +283,7 @@
// If the state is changed to anything other than EXECUTING or TIMEDOUT here
// then the execution loop needs to be changed below.
task->state_ =
- (task->getExpireTime() && task->getExpireTime() < Util::currentTime()) ?
+ (task->getExpireTime() && *(task->getExpireTime()) < std::chrono::steady_clock::now()) ?
ThreadManager::Task::TIMEDOUT :
ThreadManager::Task::EXECUTING;
}
@@ -341,7 +344,7 @@
std::set<shared_ptr<Thread> > newThreads;
for (size_t ix = 0; ix < value; ix++) {
shared_ptr<ThreadManager::Worker> worker
- = shared_ptr<ThreadManager::Worker>(new ThreadManager::Worker(this));
+ = std::make_shared<ThreadManager::Worker>(this);
newThreads.insert(threadFactory_->newThread(worker));
}
@@ -349,13 +352,12 @@
workerMaxCount_ += value;
workers_.insert(newThreads.begin(), newThreads.end());
- for (std::set<shared_ptr<Thread> >::iterator ix = newThreads.begin(); ix != newThreads.end();
- ++ix) {
+ for (const auto & newThread : newThreads) {
shared_ptr<ThreadManager::Worker> worker
- = dynamic_pointer_cast<ThreadManager::Worker, Runnable>((*ix)->runnable());
+ = dynamic_pointer_cast<ThreadManager::Worker, Runnable>(newThread->runnable());
worker->state_ = ThreadManager::Worker::STARTING;
- (*ix)->start();
- idMap_.insert(std::pair<const Thread::id_t, shared_ptr<Thread> >((*ix)->getId(), *ix));
+ newThread->start();
+ idMap_.insert(std::pair<const Thread::id_t, shared_ptr<Thread> >(newThread->getId(), newThread));
}
while (workerCount_ != workerMaxCount_) {
@@ -427,17 +429,15 @@
workerMonitor_.wait();
}
- for (std::set<shared_ptr<Thread> >::iterator ix = deadWorkers_.begin();
- ix != deadWorkers_.end();
- ++ix) {
+ for (const auto & deadWorker : deadWorkers_) {
// when used with a joinable thread factory, we join the threads as we remove them
if (!threadFactory_->isDetached()) {
- (*ix)->join();
+ deadWorker->join();
}
- idMap_.erase((*ix)->getId());
- workers_.erase(*ix);
+ idMap_.erase(deadWorker->getId());
+ workers_.erase(deadWorker);
}
deadWorkers_.clear();
@@ -477,7 +477,7 @@
}
}
- tasks_.push_back(shared_ptr<ThreadManager::Task>(new ThreadManager::Task(value, expiration)));
+ tasks_.push_back(std::make_shared<ThreadManager::Task>(value, expiration));
// If idle thread is available notify it, otherwise all worker threads are
// running and will get around to this task in time.
@@ -494,7 +494,7 @@
"started");
}
- for (TaskQueue::iterator it = tasks_.begin(); it != tasks_.end(); ++it)
+ for (auto it = tasks_.begin(); it != tasks_.end(); ++it)
{
if ((*it)->getRunnable() == task)
{
@@ -504,7 +504,7 @@
}
}
-stdcxx::shared_ptr<Runnable> ThreadManager::Impl::removeNextPending() {
+std::shared_ptr<Runnable> ThreadManager::Impl::removeNextPending() {
Guard g(mutex_);
if (state_ != ThreadManager::STARTED) {
throw IllegalStateException(
@@ -513,7 +513,7 @@
}
if (tasks_.empty()) {
- return stdcxx::shared_ptr<Runnable>();
+ return std::shared_ptr<Runnable>();
}
shared_ptr<ThreadManager::Task> task = tasks_.front();
@@ -524,15 +524,14 @@
void ThreadManager::Impl::removeExpired(bool justOne) {
// this is always called under a lock
- int64_t now = 0LL;
+ if (tasks_.empty()) {
+ return;
+ }
+ auto now = std::chrono::steady_clock::now();
- for (TaskQueue::iterator it = tasks_.begin(); it != tasks_.end(); )
+ for (auto it = tasks_.begin(); it != tasks_.end(); )
{
- if (now == 0LL) {
- now = Util::currentTime();
- }
-
- if ((*it)->getExpireTime() > 0LL && (*it)->getExpireTime() < now) {
+ if ((*it)->getExpireTime() && *((*it)->getExpireTime()) < now) {
if (expireCallback_) {
expireCallback_((*it)->getRunnable());
}
@@ -560,7 +559,7 @@
SimpleThreadManager(size_t workerCount = 4, size_t pendingTaskCountMax = 0)
: workerCount_(workerCount), pendingTaskCountMax_(pendingTaskCountMax) {}
- void start() {
+ void start() override {
ThreadManager::Impl::pendingTaskCountMax(pendingTaskCountMax_);
ThreadManager::Impl::start();
addWorker(workerCount_);
diff --git a/lib/cpp/src/thrift/concurrency/ThreadManager.h b/lib/cpp/src/thrift/concurrency/ThreadManager.h
index b3b7542..7b202ca 100644
--- a/lib/cpp/src/thrift/concurrency/ThreadManager.h
+++ b/lib/cpp/src/thrift/concurrency/ThreadManager.h
@@ -20,9 +20,9 @@
#ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_
#define _THRIFT_CONCURRENCY_THREADMANAGER_H_ 1
-#include <sys/types.h>
-#include <thrift/concurrency/Thread.h>
-#include <thrift/stdcxx.h>
+#include <functional>
+#include <memory>
+#include <thrift/concurrency/ThreadFactory.h>
namespace apache {
namespace thrift {
@@ -55,12 +55,12 @@
class ThreadManager {
protected:
- ThreadManager() {}
+ ThreadManager() = default;
public:
- typedef apache::thrift::stdcxx::function<void(stdcxx::shared_ptr<Runnable>)> ExpireCallback;
+ typedef std::function<void(std::shared_ptr<Runnable>)> ExpireCallback;
- virtual ~ThreadManager() {}
+ virtual ~ThreadManager() = default;
/**
* Starts the thread manager. Verifies all attributes have been properly
@@ -87,14 +87,14 @@
/**
* \returns the current thread factory
*/
- virtual stdcxx::shared_ptr<ThreadFactory> threadFactory() const = 0;
+ virtual std::shared_ptr<ThreadFactory> threadFactory() const = 0;
/**
* Set the thread factory.
* \throws InvalidArgumentException if the new thread factory has a different
* detached disposition than the one replacing it
*/
- virtual void threadFactory(stdcxx::shared_ptr<ThreadFactory> value) = 0;
+ virtual void threadFactory(std::shared_ptr<ThreadFactory> value) = 0;
/**
* Adds worker thread(s).
@@ -140,7 +140,7 @@
* Gets the number of tasks which have been expired without being run
* since start() was called.
*/
- virtual size_t expiredTaskCount() = 0;
+ virtual size_t expiredTaskCount() const = 0;
/**
* Adds a task to be executed at some time in the future by a worker thread.
@@ -161,21 +161,21 @@
*
* @throws TooManyPendingTasksException Pending task count exceeds max pending task count
*/
- virtual void add(stdcxx::shared_ptr<Runnable> task,
+ virtual void add(std::shared_ptr<Runnable> task,
int64_t timeout = 0LL,
int64_t expiration = 0LL) = 0;
/**
* Removes a pending task
*/
- virtual void remove(stdcxx::shared_ptr<Runnable> task) = 0;
+ virtual void remove(std::shared_ptr<Runnable> task) = 0;
/**
* Remove the next pending task which would be run.
*
* @return the task removed.
*/
- virtual stdcxx::shared_ptr<Runnable> removeNextPending() = 0;
+ virtual std::shared_ptr<Runnable> removeNextPending() = 0;
/**
* Remove tasks from front of task queue that have expired.
@@ -190,14 +190,14 @@
*/
virtual void setExpireCallback(ExpireCallback expireCallback) = 0;
- static stdcxx::shared_ptr<ThreadManager> newThreadManager();
+ static std::shared_ptr<ThreadManager> newThreadManager();
/**
* Creates a simple thread manager the uses count number of worker threads and has
* a pendingTaskCountMax maximum pending tasks. The default, 0, specified no limit
* on pending tasks
*/
- static stdcxx::shared_ptr<ThreadManager> newSimpleThreadManager(size_t count = 4,
+ static std::shared_ptr<ThreadManager> newSimpleThreadManager(size_t count = 4,
size_t pendingTaskCountMax = 0);
class Task;
diff --git a/lib/cpp/src/thrift/concurrency/TimerManager.cpp b/lib/cpp/src/thrift/concurrency/TimerManager.cpp
index 2017146..003f564 100644
--- a/lib/cpp/src/thrift/concurrency/TimerManager.cpp
+++ b/lib/cpp/src/thrift/concurrency/TimerManager.cpp
@@ -19,18 +19,18 @@
#include <thrift/concurrency/TimerManager.h>
#include <thrift/concurrency/Exception.h>
-#include <thrift/concurrency/Util.h>
#include <assert.h>
#include <iostream>
+#include <memory>
#include <set>
namespace apache {
namespace thrift {
namespace concurrency {
-using stdcxx::shared_ptr;
-using stdcxx::weak_ptr;
+using std::shared_ptr;
+using std::weak_ptr;
/**
* TimerManager class
@@ -44,9 +44,9 @@
Task(shared_ptr<Runnable> runnable) : runnable_(runnable), state_(WAITING) {}
- ~Task() {}
+ ~Task() override = default;
- void run() {
+ void run() override {
if (state_ == EXECUTING) {
runnable_->run();
state_ = COMPLETE;
@@ -68,7 +68,7 @@
public:
Dispatcher(TimerManager* manager) : manager_(manager) {}
- ~Dispatcher() {}
+ ~Dispatcher() override = default;
/**
* Dispatcher entry point
@@ -76,7 +76,7 @@
* As long as dispatcher thread is running, pull tasks off the task taskMap_
* and execute.
*/
- void run() {
+ void run() override {
{
Synchronized s(manager_->monitor_);
if (manager_->state_ == TimerManager::STARTING) {
@@ -90,25 +90,26 @@
{
Synchronized s(manager_->monitor_);
task_iterator expiredTaskEnd;
- int64_t now = Util::currentTime();
+ auto now = std::chrono::steady_clock::now();
while (manager_->state_ == TimerManager::STARTED
&& (expiredTaskEnd = manager_->taskMap_.upper_bound(now))
== manager_->taskMap_.begin()) {
- int64_t timeout = 0LL;
+ std::chrono::milliseconds timeout(0);
if (!manager_->taskMap_.empty()) {
- timeout = manager_->taskMap_.begin()->first - now;
+ timeout = std::chrono::duration_cast<std::chrono::milliseconds>(manager_->taskMap_.begin()->first - now);
+ //because the unit of steady_clock is smaller than millisecond,timeout may be 0.
+ if (timeout.count() == 0) {
+ timeout = std::chrono::milliseconds(1);
+ }
+ manager_->monitor_.waitForTimeRelative(timeout);
+ } else {
+ manager_->monitor_.waitForTimeRelative(0);
}
- assert((timeout != 0 && manager_->taskCount_ > 0)
- || (timeout == 0 && manager_->taskCount_ == 0));
- try {
- manager_->monitor_.wait(timeout);
- } catch (TimedOutException&) {
- }
- now = Util::currentTime();
+ now = std::chrono::steady_clock::now();
}
if (manager_->state_ == TimerManager::STARTED) {
- for (task_iterator ix = manager_->taskMap_.begin(); ix != expiredTaskEnd; ix++) {
+ for (auto ix = manager_->taskMap_.begin(); ix != expiredTaskEnd; ix++) {
shared_ptr<TimerManager::Task> task = ix->second;
expiredTasks.insert(task);
task->it_ = manager_->taskMap_.end();
@@ -121,10 +122,8 @@
}
}
- for (std::set<shared_ptr<Task> >::iterator ix = expiredTasks.begin();
- ix != expiredTasks.end();
- ++ix) {
- (*ix)->run();
+ for (const auto & expiredTask : expiredTasks) {
+ expiredTask->run();
}
} while (manager_->state_ == TimerManager::STARTED);
@@ -152,7 +151,7 @@
TimerManager::TimerManager()
: taskCount_(0),
state_(TimerManager::UNINITIALIZED),
- dispatcher_(shared_ptr<Dispatcher>(new Dispatcher(this))) {
+ dispatcher_(std::make_shared<Dispatcher>(this)) {
}
#if defined(_MSC_VER)
@@ -221,7 +220,7 @@
taskMap_.clear();
// Remove dispatcher's reference to us.
- dispatcher_->manager_ = NULL;
+ dispatcher_->manager_ = nullptr;
}
}
@@ -239,64 +238,39 @@
return taskCount_;
}
-TimerManager::Timer TimerManager::add(shared_ptr<Runnable> task, int64_t timeout) {
- int64_t now = Util::currentTime();
- timeout += now;
-
- {
- Synchronized s(monitor_);
- if (state_ != TimerManager::STARTED) {
- throw IllegalStateException();
- }
-
- // If the task map is empty, we will kick the dispatcher for sure. Otherwise, we kick him
- // if the expiration time is shorter than the current value. Need to test before we insert,
- // because the new task might insert at the front.
- bool notifyRequired = (taskCount_ == 0) ? true : timeout < taskMap_.begin()->first;
-
- shared_ptr<Task> timer(new Task(task));
- taskCount_++;
- timer->it_ = taskMap_.insert(std::pair<int64_t, shared_ptr<Task> >(timeout, timer));
-
- // If the task map was empty, or if we have an expiration that is earlier
- // than any previously seen, kick the dispatcher so it can update its
- // timeout
- if (notifyRequired) {
- monitor_.notify();
- }
-
- return timer;
- }
+TimerManager::Timer TimerManager::add(shared_ptr<Runnable> task, const std::chrono::milliseconds &timeout) {
+ return add(task, std::chrono::steady_clock::now() + timeout);
}
TimerManager::Timer TimerManager::add(shared_ptr<Runnable> task,
- const struct THRIFT_TIMESPEC& value) {
+ const std::chrono::time_point<std::chrono::steady_clock>& abstime) {
+ auto now = std::chrono::steady_clock::now();
- int64_t expiration;
- Util::toMilliseconds(expiration, value);
-
- int64_t now = Util::currentTime();
-
- if (expiration < now) {
+ if (abstime < now) {
throw InvalidArgumentException();
}
-
- return add(task, expiration - now);
-}
-
-TimerManager::Timer TimerManager::add(shared_ptr<Runnable> task,
- const struct timeval& value) {
-
- int64_t expiration;
- Util::toMilliseconds(expiration, value);
-
- int64_t now = Util::currentTime();
-
- if (expiration < now) {
- throw InvalidArgumentException();
+ Synchronized s(monitor_);
+ if (state_ != TimerManager::STARTED) {
+ throw IllegalStateException();
}
- return add(task, expiration - now);
+ // If the task map is empty, we will kick the dispatcher for sure. Otherwise, we kick him
+ // if the expiration time is shorter than the current value. Need to test before we insert,
+ // because the new task might insert at the front.
+ bool notifyRequired = (taskCount_ == 0) ? true : abstime < taskMap_.begin()->first;
+
+ shared_ptr<Task> timer(new Task(task));
+ taskCount_++;
+ timer->it_ = taskMap_.emplace(abstime, timer);
+
+ // If the task map was empty, or if we have an expiration that is earlier
+ // than any previously seen, kick the dispatcher so it can update its
+ // timeout
+ if (notifyRequired) {
+ monitor_.notify();
+ }
+
+ return timer;
}
void TimerManager::remove(shared_ptr<Runnable> task) {
@@ -305,7 +279,7 @@
throw IllegalStateException();
}
bool found = false;
- for (task_iterator ix = taskMap_.begin(); ix != taskMap_.end();) {
+ for (auto ix = taskMap_.begin(); ix != taskMap_.end();) {
if (*ix->second == task) {
found = true;
taskCount_--;
diff --git a/lib/cpp/src/thrift/concurrency/TimerManager.h b/lib/cpp/src/thrift/concurrency/TimerManager.h
index 2bfc6a7..44d4738 100644
--- a/lib/cpp/src/thrift/concurrency/TimerManager.h
+++ b/lib/cpp/src/thrift/concurrency/TimerManager.h
@@ -20,13 +20,11 @@
#ifndef _THRIFT_CONCURRENCY_TIMERMANAGER_H_
#define _THRIFT_CONCURRENCY_TIMERMANAGER_H_ 1
-#include <thrift/concurrency/Exception.h>
#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/Thread.h>
+#include <thrift/concurrency/ThreadFactory.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <map>
-#include <time.h>
namespace apache {
namespace thrift {
@@ -43,15 +41,15 @@
public:
class Task;
- typedef stdcxx::weak_ptr<Task> Timer;
+ typedef std::weak_ptr<Task> Timer;
TimerManager();
virtual ~TimerManager();
- virtual stdcxx::shared_ptr<const ThreadFactory> threadFactory() const;
+ virtual std::shared_ptr<const ThreadFactory> threadFactory() const;
- virtual void threadFactory(stdcxx::shared_ptr<const ThreadFactory> value);
+ virtual void threadFactory(std::shared_ptr<const ThreadFactory> value);
/**
* Starts the timer manager service
@@ -74,25 +72,17 @@
* @param timeout Time in milliseconds to delay before executing task
* @return Handle of the timer, which can be used to remove the timer.
*/
- virtual Timer add(stdcxx::shared_ptr<Runnable> task, int64_t timeout);
+ virtual Timer add(std::shared_ptr<Runnable> task, const std::chrono::milliseconds &timeout);
+ Timer add(std::shared_ptr<Runnable> task, uint64_t timeout) { return add(task,std::chrono::milliseconds(timeout)); }
/**
* Adds a task to be executed at some time in the future by a worker thread.
*
* @param task The task to execute
- * @param timeout Absolute time in the future to execute task.
+ * @param abstime Absolute time in the future to execute task.
* @return Handle of the timer, which can be used to remove the timer.
*/
- virtual Timer add(stdcxx::shared_ptr<Runnable> task, const struct THRIFT_TIMESPEC& timeout);
-
- /**
- * Adds a task to be executed at some time in the future by a worker thread.
- *
- * @param task The task to execute
- * @param timeout Absolute time in the future to execute task.
- * @return Handle of the timer, which can be used to remove the timer.
- */
- virtual Timer add(stdcxx::shared_ptr<Runnable> task, const struct timeval& timeout);
+ virtual Timer add(std::shared_ptr<Runnable> task, const std::chrono::time_point<std::chrono::steady_clock>& abstime);
/**
* Removes a pending task
@@ -106,7 +96,7 @@
* @throws UncancellableTaskException Specified task is already being
* executed or has completed execution.
*/
- virtual void remove(stdcxx::shared_ptr<Runnable> task);
+ virtual void remove(std::shared_ptr<Runnable> task);
/**
* Removes a single pending task
@@ -127,17 +117,17 @@
virtual STATE state() const;
private:
- stdcxx::shared_ptr<const ThreadFactory> threadFactory_;
+ std::shared_ptr<const ThreadFactory> threadFactory_;
friend class Task;
- std::multimap<int64_t, stdcxx::shared_ptr<Task> > taskMap_;
+ std::multimap<std::chrono::time_point<std::chrono::steady_clock>, std::shared_ptr<Task> > taskMap_;
size_t taskCount_;
Monitor monitor_;
STATE state_;
class Dispatcher;
friend class Dispatcher;
- stdcxx::shared_ptr<Dispatcher> dispatcher_;
- stdcxx::shared_ptr<Thread> dispatcherThread_;
- typedef std::multimap<int64_t, stdcxx::shared_ptr<TimerManager::Task> >::iterator task_iterator;
+ std::shared_ptr<Dispatcher> dispatcher_;
+ std::shared_ptr<Thread> dispatcherThread_;
+ using task_iterator = decltype(taskMap_)::iterator;
typedef std::pair<task_iterator, task_iterator> task_range;
};
}
diff --git a/lib/cpp/src/thrift/concurrency/Util.h b/lib/cpp/src/thrift/concurrency/Util.h
deleted file mode 100644
index 1a91599..0000000
--- a/lib/cpp/src/thrift/concurrency/Util.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _THRIFT_CONCURRENCY_UTIL_H_
-#define _THRIFT_CONCURRENCY_UTIL_H_ 1
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <time.h>
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#include <thrift/transport/PlatformSocket.h>
-
-namespace apache {
-namespace thrift {
-namespace concurrency {
-
-/**
- * Utility methods
- *
- * This class contains basic utility methods for converting time formats,
- * and other common platform-dependent concurrency operations.
- * It should not be included in API headers for other concurrency library
- * headers, since it will, by definition, pull in all sorts of horrid
- * platform dependent stuff. Rather it should be inluded directly in
- * concurrency library implementation source.
- *
- * @version $Id:$
- */
-class Util {
-
- static const int64_t NS_PER_S = 1000000000LL;
- static const int64_t US_PER_S = 1000000LL;
- static const int64_t MS_PER_S = 1000LL;
-
- static const int64_t NS_PER_MS = NS_PER_S / MS_PER_S;
- static const int64_t NS_PER_US = NS_PER_S / US_PER_S;
- static const int64_t US_PER_MS = US_PER_S / MS_PER_S;
-
-public:
- /**
- * Converts millisecond timestamp into a THRIFT_TIMESPEC struct
- *
- * @param struct THRIFT_TIMESPEC& result
- * @param time or duration in milliseconds
- */
- static void toTimespec(struct THRIFT_TIMESPEC& result, int64_t value) {
- result.tv_sec = value / MS_PER_S; // ms to s
- result.tv_nsec = (value % MS_PER_S) * NS_PER_MS; // ms to ns
- }
-
- static void toTimeval(struct timeval& result, int64_t value) {
- result.tv_sec = static_cast<uint32_t>(value / MS_PER_S); // ms to s
- result.tv_usec = static_cast<uint32_t>((value % MS_PER_S) * US_PER_MS); // ms to us
- }
-
- static void toTicks(int64_t& result,
- int64_t secs,
- int64_t oldTicks,
- int64_t oldTicksPerSec,
- int64_t newTicksPerSec) {
- result = secs * newTicksPerSec;
- result += oldTicks * newTicksPerSec / oldTicksPerSec;
-
- int64_t oldPerNew = oldTicksPerSec / newTicksPerSec;
- if (oldPerNew && ((oldTicks % oldPerNew) >= (oldPerNew / 2))) {
- ++result;
- }
- }
- /**
- * Converts struct THRIFT_TIMESPEC to arbitrary-sized ticks since epoch
- */
- static void toTicks(int64_t& result, const struct THRIFT_TIMESPEC& value, int64_t ticksPerSec) {
- return toTicks(result, value.tv_sec, value.tv_nsec, NS_PER_S, ticksPerSec);
- }
-
- /**
- * Converts struct timeval to arbitrary-sized ticks since epoch
- */
- static void toTicks(int64_t& result, const struct timeval& value, int64_t ticksPerSec) {
- return toTicks(result, (unsigned long)value.tv_sec, (unsigned long)value.tv_usec, US_PER_S, ticksPerSec);
- }
-
- /**
- * Converts struct THRIFT_TIMESPEC to milliseconds
- */
- static void toMilliseconds(int64_t& result, const struct THRIFT_TIMESPEC& value) {
- return toTicks(result, value, MS_PER_S);
- }
-
- /**
- * Converts struct timeval to milliseconds
- */
- static void toMilliseconds(int64_t& result, const struct timeval& value) {
- return toTicks(result, value, MS_PER_S);
- }
-
- /**
- * Converts struct THRIFT_TIMESPEC to microseconds
- */
- static void toUsec(int64_t& result, const struct THRIFT_TIMESPEC& value) {
- return toTicks(result, value, US_PER_S);
- }
-
- /**
- * Converts struct timeval to microseconds
- */
- static void toUsec(int64_t& result, const struct timeval& value) {
- return toTicks(result, value, US_PER_S);
- }
-
- /**
- * Get current time as a number of arbitrary-size ticks from epoch
- */
- static int64_t currentTimeTicks(int64_t ticksPerSec);
-
- /**
- * Get current time as milliseconds from epoch
- */
- static int64_t currentTime() { return currentTimeTicks(MS_PER_S); }
-
- /**
- * Get current time as micros from epoch
- */
- static int64_t currentTimeUsec() { return currentTimeTicks(US_PER_S); }
-};
-}
-}
-} // apache::thrift::concurrency
-
-#endif // #ifndef _THRIFT_CONCURRENCY_UTIL_H_
diff --git a/lib/cpp/src/thrift/processor/PeekProcessor.cpp b/lib/cpp/src/thrift/processor/PeekProcessor.cpp
index fa11a72..4cd58b8 100644
--- a/lib/cpp/src/thrift/processor/PeekProcessor.cpp
+++ b/lib/cpp/src/thrift/processor/PeekProcessor.cpp
@@ -31,29 +31,28 @@
memoryBuffer_.reset(new TMemoryBuffer());
targetTransport_ = memoryBuffer_;
}
-PeekProcessor::~PeekProcessor() {
-}
+PeekProcessor::~PeekProcessor() = default;
-void PeekProcessor::initialize(stdcxx::shared_ptr<TProcessor> actualProcessor,
- stdcxx::shared_ptr<TProtocolFactory> protocolFactory,
- stdcxx::shared_ptr<TPipedTransportFactory> transportFactory) {
+void PeekProcessor::initialize(std::shared_ptr<TProcessor> actualProcessor,
+ std::shared_ptr<TProtocolFactory> protocolFactory,
+ std::shared_ptr<TPipedTransportFactory> transportFactory) {
actualProcessor_ = actualProcessor;
pipedProtocol_ = protocolFactory->getProtocol(targetTransport_);
transportFactory_ = transportFactory;
transportFactory_->initializeTargetTransport(targetTransport_);
}
-stdcxx::shared_ptr<TTransport> PeekProcessor::getPipedTransport(stdcxx::shared_ptr<TTransport> in) {
+std::shared_ptr<TTransport> PeekProcessor::getPipedTransport(std::shared_ptr<TTransport> in) {
return transportFactory_->getTransport(in);
}
-void PeekProcessor::setTargetTransport(stdcxx::shared_ptr<TTransport> targetTransport) {
+void PeekProcessor::setTargetTransport(std::shared_ptr<TTransport> targetTransport) {
targetTransport_ = targetTransport;
- if (stdcxx::dynamic_pointer_cast<TMemoryBuffer>(targetTransport_)) {
- memoryBuffer_ = stdcxx::dynamic_pointer_cast<TMemoryBuffer>(targetTransport);
- } else if (stdcxx::dynamic_pointer_cast<TPipedTransport>(targetTransport_)) {
- memoryBuffer_ = stdcxx::dynamic_pointer_cast<TMemoryBuffer>(
- stdcxx::dynamic_pointer_cast<TPipedTransport>(targetTransport_)->getTargetTransport());
+ if (std::dynamic_pointer_cast<TMemoryBuffer>(targetTransport_)) {
+ memoryBuffer_ = std::dynamic_pointer_cast<TMemoryBuffer>(targetTransport);
+ } else if (std::dynamic_pointer_cast<TPipedTransport>(targetTransport_)) {
+ memoryBuffer_ = std::dynamic_pointer_cast<TMemoryBuffer>(
+ std::dynamic_pointer_cast<TPipedTransport>(targetTransport_)->getTargetTransport());
}
if (!memoryBuffer_) {
@@ -62,8 +61,8 @@
}
}
-bool PeekProcessor::process(stdcxx::shared_ptr<TProtocol> in,
- stdcxx::shared_ptr<TProtocol> out,
+bool PeekProcessor::process(std::shared_ptr<TProtocol> in,
+ std::shared_ptr<TProtocol> out,
void* connectionContext) {
std::string fname;
@@ -120,7 +119,7 @@
(void)size;
}
-void PeekProcessor::peek(stdcxx::shared_ptr<TProtocol> in, TType ftype, int16_t fid) {
+void PeekProcessor::peek(std::shared_ptr<TProtocol> in, TType ftype, int16_t fid) {
(void)fid;
in->skip(ftype);
}
diff --git a/lib/cpp/src/thrift/processor/PeekProcessor.h b/lib/cpp/src/thrift/processor/PeekProcessor.h
index f5c10da..ae565fc 100644
--- a/lib/cpp/src/thrift/processor/PeekProcessor.h
+++ b/lib/cpp/src/thrift/processor/PeekProcessor.h
@@ -25,7 +25,7 @@
#include <thrift/transport/TTransport.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/transport/TBufferTransports.h>
-#include <thrift/stdcxx.h>
+#include <memory>
namespace apache {
namespace thrift {
@@ -40,41 +40,41 @@
public:
PeekProcessor();
- virtual ~PeekProcessor();
+ ~PeekProcessor() override;
// Input here: actualProcessor - the underlying processor
// protocolFactory - the protocol factory used to wrap the memory buffer
// transportFactory - this TPipedTransportFactory is used to wrap the source transport
// via a call to getPipedTransport
void initialize(
- stdcxx::shared_ptr<apache::thrift::TProcessor> actualProcessor,
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory> protocolFactory,
- stdcxx::shared_ptr<apache::thrift::transport::TPipedTransportFactory> transportFactory);
+ std::shared_ptr<apache::thrift::TProcessor> actualProcessor,
+ std::shared_ptr<apache::thrift::protocol::TProtocolFactory> protocolFactory,
+ std::shared_ptr<apache::thrift::transport::TPipedTransportFactory> transportFactory);
- stdcxx::shared_ptr<apache::thrift::transport::TTransport> getPipedTransport(
- stdcxx::shared_ptr<apache::thrift::transport::TTransport> in);
+ std::shared_ptr<apache::thrift::transport::TTransport> getPipedTransport(
+ std::shared_ptr<apache::thrift::transport::TTransport> in);
- void setTargetTransport(stdcxx::shared_ptr<apache::thrift::transport::TTransport> targetTransport);
+ void setTargetTransport(std::shared_ptr<apache::thrift::transport::TTransport> targetTransport);
- virtual bool process(stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> in,
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> out,
- void* connectionContext);
+ bool process(std::shared_ptr<apache::thrift::protocol::TProtocol> in,
+ std::shared_ptr<apache::thrift::protocol::TProtocol> out,
+ void* connectionContext) override;
// The following three functions can be overloaded by child classes to
// achieve desired peeking behavior
virtual void peekName(const std::string& fname);
virtual void peekBuffer(uint8_t* buffer, uint32_t size);
- virtual void peek(stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> in,
+ virtual void peek(std::shared_ptr<apache::thrift::protocol::TProtocol> in,
apache::thrift::protocol::TType ftype,
int16_t fid);
virtual void peekEnd();
private:
- stdcxx::shared_ptr<apache::thrift::TProcessor> actualProcessor_;
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> pipedProtocol_;
- stdcxx::shared_ptr<apache::thrift::transport::TPipedTransportFactory> transportFactory_;
- stdcxx::shared_ptr<apache::thrift::transport::TMemoryBuffer> memoryBuffer_;
- stdcxx::shared_ptr<apache::thrift::transport::TTransport> targetTransport_;
+ std::shared_ptr<apache::thrift::TProcessor> actualProcessor_;
+ std::shared_ptr<apache::thrift::protocol::TProtocol> pipedProtocol_;
+ std::shared_ptr<apache::thrift::transport::TPipedTransportFactory> transportFactory_;
+ std::shared_ptr<apache::thrift::transport::TMemoryBuffer> memoryBuffer_;
+ std::shared_ptr<apache::thrift::transport::TTransport> targetTransport_;
};
}
}
diff --git a/lib/cpp/src/thrift/processor/StatsProcessor.h b/lib/cpp/src/thrift/processor/StatsProcessor.h
index 8f6725f..e98efb8 100644
--- a/lib/cpp/src/thrift/processor/StatsProcessor.h
+++ b/lib/cpp/src/thrift/processor/StatsProcessor.h
@@ -20,7 +20,7 @@
#ifndef STATSPROCESSOR_H
#define STATSPROCESSOR_H
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/transport/TTransport.h>
#include <thrift/protocol/TProtocol.h>
#include <TProcessor.h>
@@ -38,8 +38,8 @@
StatsProcessor(bool print, bool frequency) : print_(print), frequency_(frequency) {}
virtual ~StatsProcessor(){};
- virtual bool process(stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> piprot,
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> poprot,
+ virtual bool process(std::shared_ptr<apache::thrift::protocol::TProtocol> piprot,
+ std::shared_ptr<apache::thrift::protocol::TProtocol> poprot,
void* serverContext) {
piprot_ = piprot;
@@ -229,7 +229,7 @@
}
}
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> piprot_;
+ std::shared_ptr<apache::thrift::protocol::TProtocol> piprot_;
std::map<std::string, int64_t> frequency_map_;
bool print_;
diff --git a/lib/cpp/src/thrift/processor/TMultiplexedProcessor.h b/lib/cpp/src/thrift/processor/TMultiplexedProcessor.h
index aa3d49f..85c0aff 100644
--- a/lib/cpp/src/thrift/processor/TMultiplexedProcessor.h
+++ b/lib/cpp/src/thrift/processor/TMultiplexedProcessor.h
@@ -36,13 +36,13 @@
*/
class StoredMessageProtocol : public TProtocolDecorator {
public:
- StoredMessageProtocol(stdcxx::shared_ptr<protocol::TProtocol> _protocol,
+ StoredMessageProtocol(std::shared_ptr<protocol::TProtocol> _protocol,
const std::string& _name,
const TMessageType _type,
const int32_t _seqid)
: TProtocolDecorator(_protocol), name(_name), type(_type), seqid(_seqid) {}
- uint32_t readMessageBegin_virt(std::string& _name, TMessageType& _type, int32_t& _seqid) {
+ uint32_t readMessageBegin_virt(std::string& _name, TMessageType& _type, int32_t& _seqid) override {
_name = name;
_type = type;
@@ -65,19 +65,19 @@
* processors with it, as shown in the following example:</p>
*
* <blockquote><code>
- * stdcxx::shared_ptr<TMultiplexedProcessor> processor(new TMultiplexedProcessor());
+ * std::shared_ptr<TMultiplexedProcessor> processor(new TMultiplexedProcessor());
*
* processor->registerProcessor(
* "Calculator",
- * stdcxx::shared_ptr<TProcessor>( new CalculatorProcessor(
- * stdcxx::shared_ptr<CalculatorHandler>( new CalculatorHandler()))));
+ * std::shared_ptr<TProcessor>( new CalculatorProcessor(
+ * std::shared_ptr<CalculatorHandler>( new CalculatorHandler()))));
*
* processor->registerProcessor(
* "WeatherReport",
- * stdcxx::shared_ptr<TProcessor>( new WeatherReportProcessor(
- * stdcxx::shared_ptr<WeatherReportHandler>( new WeatherReportHandler()))));
+ * std::shared_ptr<TProcessor>( new WeatherReportProcessor(
+ * std::shared_ptr<WeatherReportHandler>( new WeatherReportHandler()))));
*
- * stdcxx::shared_ptr<TServerTransport> transport(new TServerSocket(9090));
+ * std::shared_ptr<TServerTransport> transport(new TServerSocket(9090));
* TSimpleServer server(processor, transport);
*
* server.serve();
@@ -85,7 +85,7 @@
*/
class TMultiplexedProcessor : public TProcessor {
public:
- typedef std::map<std::string, stdcxx::shared_ptr<TProcessor> > services_t;
+ typedef std::map<std::string, std::shared_ptr<TProcessor> > services_t;
/**
* 'Register' a service with this <code>TMultiplexedProcessor</code>. This
@@ -98,7 +98,7 @@
* as "handlers", e.g. WeatherReportHandler,
* implementing WeatherReportIf interface.
*/
- void registerProcessor(const std::string& serviceName, stdcxx::shared_ptr<TProcessor> processor) {
+ void registerProcessor(const std::string& serviceName, std::shared_ptr<TProcessor> processor) {
services[serviceName] = processor;
}
@@ -106,15 +106,15 @@
* Register a service to be called to process queries without service name
* \param [in] processor Implementation of a service.
*/
- void registerDefault(const stdcxx::shared_ptr<TProcessor>& processor) {
+ void registerDefault(const std::shared_ptr<TProcessor>& processor) {
defaultProcessor = processor;
}
/**
* Chew up invalid input and return an exception to throw.
*/
- TException protocol_error(stdcxx::shared_ptr<protocol::TProtocol> in,
- stdcxx::shared_ptr<protocol::TProtocol> out,
+ TException protocol_error(std::shared_ptr<protocol::TProtocol> in,
+ std::shared_ptr<protocol::TProtocol> out,
const std::string& name,
int32_t seqid,
const std::string& msg) const {
@@ -147,9 +147,9 @@
* the service name was not found in the message, or if the service
* name was not found in the service map.
*/
- bool process(stdcxx::shared_ptr<protocol::TProtocol> in,
- stdcxx::shared_ptr<protocol::TProtocol> out,
- void* connectionContext) {
+ bool process(std::shared_ptr<protocol::TProtocol> in,
+ std::shared_ptr<protocol::TProtocol> out,
+ void* connectionContext) override {
std::string name;
protocol::TMessageType type;
int32_t seqid;
@@ -174,14 +174,14 @@
// name and the name of the method to call.
if (tokens.size() == 2) {
// Search for a processor associated with this service name.
- services_t::iterator it = services.find(tokens[0]);
+ auto it = services.find(tokens[0]);
if (it != services.end()) {
- stdcxx::shared_ptr<TProcessor> processor = it->second;
+ std::shared_ptr<TProcessor> processor = it->second;
// Let the processor registered for this service name
// process the message.
return processor
- ->process(stdcxx::shared_ptr<protocol::TProtocol>(
+ ->process(std::shared_ptr<protocol::TProtocol>(
new protocol::StoredMessageProtocol(in, tokens[1], type, seqid)),
out,
connectionContext);
@@ -195,7 +195,7 @@
if (defaultProcessor) {
// non-multiplexed client forwards to default processor
return defaultProcessor
- ->process(stdcxx::shared_ptr<protocol::TProtocol>(
+ ->process(std::shared_ptr<protocol::TProtocol>(
new protocol::StoredMessageProtocol(in, tokens[0], type, seqid)),
out,
connectionContext);
@@ -216,7 +216,7 @@
//! If a non-multi client requests something, it goes to the
//! default processor (if one is defined) for backwards compatibility.
- stdcxx::shared_ptr<TProcessor> defaultProcessor;
+ std::shared_ptr<TProcessor> defaultProcessor;
};
}
}
diff --git a/lib/cpp/src/thrift/protocol/TBase64Utils.cpp b/lib/cpp/src/thrift/protocol/TBase64Utils.cpp
index beb76eb..7474f5a 100644
--- a/lib/cpp/src/thrift/protocol/TBase64Utils.cpp
+++ b/lib/cpp/src/thrift/protocol/TBase64Utils.cpp
@@ -19,8 +19,6 @@
#include <thrift/protocol/TBase64Utils.h>
-#include <boost/static_assert.hpp>
-
using std::string;
namespace apache {
diff --git a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h
index f28d278..6bd5fb8 100644
--- a/lib/cpp/src/thrift/protocol/TBinaryProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TBinaryProtocol.h
@@ -23,7 +23,7 @@
#include <thrift/protocol/TProtocol.h>
#include <thrift/protocol/TVirtualProtocol.h>
-#include <thrift/stdcxx.h>
+#include <memory>
namespace apache {
namespace thrift {
@@ -41,7 +41,7 @@
static const int32_t VERSION_1 = ((int32_t)0x80010000);
// VERSION_2 (0x80020000) was taken by TDenseProtocol (which has since been removed)
- TBinaryProtocolT(stdcxx::shared_ptr<Transport_> trans)
+ TBinaryProtocolT(std::shared_ptr<Transport_> trans)
: TVirtualProtocol<TBinaryProtocolT<Transport_, ByteOrder_> >(trans),
trans_(trans.get()),
string_limit_(0),
@@ -49,7 +49,7 @@
strict_read_(false),
strict_write_(true) {}
- TBinaryProtocolT(stdcxx::shared_ptr<Transport_> trans,
+ TBinaryProtocolT(std::shared_ptr<Transport_> trans,
int32_t string_limit,
int32_t container_limit,
bool strict_read,
@@ -201,7 +201,7 @@
strict_read_(strict_read),
strict_write_(strict_write) {}
- virtual ~TBinaryProtocolFactoryT() {}
+ ~TBinaryProtocolFactoryT() override = default;
void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; }
@@ -212,8 +212,8 @@
strict_write_ = strict_write;
}
- stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> trans) {
- stdcxx::shared_ptr<Transport_> specific_trans = stdcxx::dynamic_pointer_cast<Transport_>(trans);
+ std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> trans) override {
+ std::shared_ptr<Transport_> specific_trans = std::dynamic_pointer_cast<Transport_>(trans);
TProtocol* prot;
if (specific_trans) {
prot = new TBinaryProtocolT<Transport_, ByteOrder_>(specific_trans,
@@ -229,7 +229,7 @@
strict_write_);
}
- return stdcxx::shared_ptr<TProtocol>(prot);
+ return std::shared_ptr<TProtocol>(prot);
}
private:
diff --git a/lib/cpp/src/thrift/protocol/TBinaryProtocol.tcc b/lib/cpp/src/thrift/protocol/TBinaryProtocol.tcc
index d6f6dbb..2964f25 100644
--- a/lib/cpp/src/thrift/protocol/TBinaryProtocol.tcc
+++ b/lib/cpp/src/thrift/protocol/TBinaryProtocol.tcc
@@ -144,31 +144,31 @@
template <class Transport_, class ByteOrder_>
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI16(const int16_t i16) {
- int16_t net = (int16_t)ByteOrder_::toWire16(i16);
+ auto net = (int16_t)ByteOrder_::toWire16(i16);
this->trans_->write((uint8_t*)&net, 2);
return 2;
}
template <class Transport_, class ByteOrder_>
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI32(const int32_t i32) {
- int32_t net = (int32_t)ByteOrder_::toWire32(i32);
+ auto net = (int32_t)ByteOrder_::toWire32(i32);
this->trans_->write((uint8_t*)&net, 4);
return 4;
}
template <class Transport_, class ByteOrder_>
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeI64(const int64_t i64) {
- int64_t net = (int64_t)ByteOrder_::toWire64(i64);
+ auto net = (int64_t)ByteOrder_::toWire64(i64);
this->trans_->write((uint8_t*)&net, 8);
return 8;
}
template <class Transport_, class ByteOrder_>
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeDouble(const double dub) {
- BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
- BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
+ static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)");
+ static_assert(std::numeric_limits<double>::is_iec559, "std::numeric_limits<double>::is_iec559");
- uint64_t bits = bitwise_cast<uint64_t>(dub);
+ auto bits = bitwise_cast<uint64_t>(dub);
bits = ByteOrder_::toWire64(bits);
this->trans_->write((uint8_t*)&bits, 8);
return 8;
@@ -179,7 +179,7 @@
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::writeString(const StrType& str) {
if (str.size() > static_cast<size_t>((std::numeric_limits<int32_t>::max)()))
throw TProtocolException(TProtocolException::SIZE_LIMIT);
- uint32_t size = static_cast<uint32_t>(str.size());
+ auto size = static_cast<uint32_t>(str.size());
uint32_t result = writeI32((int32_t)size);
if (size > 0) {
this->trans_->write((uint8_t*)str.data(), size);
@@ -388,8 +388,8 @@
template <class Transport_, class ByteOrder_>
uint32_t TBinaryProtocolT<Transport_, ByteOrder_>::readDouble(double& dub) {
- BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
- BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
+ static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)");
+ static_assert(std::numeric_limits<double>::is_iec559, "std::numeric_limits<double>::is_iec559");
union bytes {
uint8_t b[8];
@@ -437,7 +437,7 @@
// Try to borrow first
const uint8_t* borrow_buf;
uint32_t got = size;
- if ((borrow_buf = this->trans_->borrow(NULL, &got))) {
+ if ((borrow_buf = this->trans_->borrow(nullptr, &got))) {
str.assign((const char*)borrow_buf, size);
this->trans_->consume(size);
return size;
diff --git a/lib/cpp/src/thrift/protocol/TCompactProtocol.h b/lib/cpp/src/thrift/protocol/TCompactProtocol.h
index e6024a9..2930aba 100644
--- a/lib/cpp/src/thrift/protocol/TCompactProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TCompactProtocol.h
@@ -23,7 +23,7 @@
#include <thrift/protocol/TVirtualProtocol.h>
#include <stack>
-#include <thrift/stdcxx.h>
+#include <memory>
namespace apache {
namespace thrift {
@@ -74,33 +74,33 @@
int16_t lastFieldId_;
public:
- TCompactProtocolT(stdcxx::shared_ptr<Transport_> trans)
+ TCompactProtocolT(std::shared_ptr<Transport_> trans)
: TVirtualProtocol<TCompactProtocolT<Transport_> >(trans),
trans_(trans.get()),
lastFieldId_(0),
string_limit_(0),
- string_buf_(NULL),
+ string_buf_(nullptr),
string_buf_size_(0),
container_limit_(0) {
- booleanField_.name = NULL;
+ booleanField_.name = nullptr;
boolValue_.hasBoolValue = false;
}
- TCompactProtocolT(stdcxx::shared_ptr<Transport_> trans,
+ TCompactProtocolT(std::shared_ptr<Transport_> trans,
int32_t string_limit,
int32_t container_limit)
: TVirtualProtocol<TCompactProtocolT<Transport_> >(trans),
trans_(trans.get()),
lastFieldId_(0),
string_limit_(string_limit),
- string_buf_(NULL),
+ string_buf_(nullptr),
string_buf_size_(0),
container_limit_(container_limit) {
- booleanField_.name = NULL;
+ booleanField_.name = nullptr;
boolValue_.hasBoolValue = false;
}
- ~TCompactProtocolT() { free(string_buf_); }
+ ~TCompactProtocolT() override { free(string_buf_); }
/**
* Writing functions
@@ -233,14 +233,14 @@
TCompactProtocolFactoryT(int32_t string_limit, int32_t container_limit)
: string_limit_(string_limit), container_limit_(container_limit) {}
- virtual ~TCompactProtocolFactoryT() {}
+ ~TCompactProtocolFactoryT() override = default;
void setStringSizeLimit(int32_t string_limit) { string_limit_ = string_limit; }
void setContainerSizeLimit(int32_t container_limit) { container_limit_ = container_limit; }
- stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> trans) {
- stdcxx::shared_ptr<Transport_> specific_trans = stdcxx::dynamic_pointer_cast<Transport_>(trans);
+ std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> trans) override {
+ std::shared_ptr<Transport_> specific_trans = std::dynamic_pointer_cast<Transport_>(trans);
TProtocol* prot;
if (specific_trans) {
prot = new TCompactProtocolT<Transport_>(specific_trans, string_limit_, container_limit_);
@@ -248,7 +248,7 @@
prot = new TCompactProtocol(trans, string_limit_, container_limit_);
}
- return stdcxx::shared_ptr<TProtocol>(prot);
+ return std::shared_ptr<TProtocol>(prot);
}
private:
diff --git a/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc b/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc
index d40c331..d1e342e 100644
--- a/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc
+++ b/lib/cpp/src/thrift/protocol/TCompactProtocol.tcc
@@ -198,7 +198,7 @@
uint32_t TCompactProtocolT<Transport_>::writeBool(const bool value) {
uint32_t wsize = 0;
- if (booleanField_.name != NULL) {
+ if (booleanField_.name != nullptr) {
// we haven't written the field header yet
wsize
+= writeFieldBeginInternal(booleanField_.name,
@@ -207,7 +207,7 @@
static_cast<int8_t>(value
? detail::compact::CT_BOOLEAN_TRUE
: detail::compact::CT_BOOLEAN_FALSE));
- booleanField_.name = NULL;
+ booleanField_.name = nullptr;
} else {
// we're not part of a field, so just write the value
wsize
@@ -253,10 +253,10 @@
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::writeDouble(const double dub) {
- BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
- BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
+ static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)");
+ static_assert(std::numeric_limits<double>::is_iec559, "std::numeric_limits<double>::is_iec559");
- uint64_t bits = bitwise_cast<uint64_t>(dub);
+ auto bits = bitwise_cast<uint64_t>(dub);
bits = THRIFT_htolell(bits);
trans_->write((uint8_t*)&bits, 8);
return 8;
@@ -274,7 +274,7 @@
uint32_t TCompactProtocolT<Transport_>::writeBinary(const std::string& str) {
if(str.size() > (std::numeric_limits<uint32_t>::max)())
throw TProtocolException(TProtocolException::SIZE_LIMIT);
- uint32_t ssize = static_cast<uint32_t>(str.size());
+ auto ssize = static_cast<uint32_t>(str.size());
uint32_t wsize = writeVarint32(ssize) ;
// checking ssize + wsize > uint_max, but we don't want to overflow while checking for overflows.
// transforming the check to ssize > uint_max - wsize
@@ -488,7 +488,7 @@
}
// mask off the 4 MSB of the type header. it could contain a field id delta.
- int16_t modifier = (int16_t)(((uint8_t)byte & 0xf0) >> 4);
+ auto modifier = (int16_t)(((uint8_t)byte & 0xf0) >> 4);
if (modifier == 0) {
// not a delta, look ahead for the zigzag varint field id.
rsize += readI16(fieldId);
@@ -653,8 +653,8 @@
*/
template <class Transport_>
uint32_t TCompactProtocolT<Transport_>::readDouble(double& dub) {
- BOOST_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t));
- BOOST_STATIC_ASSERT(std::numeric_limits<double>::is_iec559);
+ static_assert(sizeof(double) == sizeof(uint64_t), "sizeof(double) == sizeof(uint64_t)");
+ static_assert(std::numeric_limits<double>::is_iec559, "std::numeric_limits<double>::is_iec559");
union {
uint64_t bits;
@@ -695,9 +695,9 @@
}
// Use the heap here to prevent stack overflow for v. large strings
- if (size > string_buf_size_ || string_buf_ == NULL) {
+ if (size > string_buf_size_ || string_buf_ == nullptr) {
void* new_string_buf = std::realloc(string_buf_, (uint32_t)size);
- if (new_string_buf == NULL) {
+ if (new_string_buf == nullptr) {
throw std::bad_alloc();
}
string_buf_ = (uint8_t*)new_string_buf;
@@ -735,7 +735,7 @@
const uint8_t* borrowed = trans_->borrow(buf, &buf_size);
// Fast path.
- if (borrowed != NULL) {
+ if (borrowed != nullptr) {
while (true) {
uint8_t byte = borrowed[rsize];
rsize++;
diff --git a/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp b/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp
index d3c6beb..0e6d4a2 100644
--- a/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp
+++ b/lib/cpp/src/thrift/protocol/TDebugProtocol.cpp
@@ -24,7 +24,6 @@
#include <cctype>
#include <cstdio>
#include <stdexcept>
-#include <boost/static_assert.hpp>
using std::string;
diff --git a/lib/cpp/src/thrift/protocol/TDebugProtocol.h b/lib/cpp/src/thrift/protocol/TDebugProtocol.h
index 301d05a..41bb0d4 100644
--- a/lib/cpp/src/thrift/protocol/TDebugProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TDebugProtocol.h
@@ -22,7 +22,7 @@
#include <thrift/protocol/TVirtualProtocol.h>
-#include <thrift/stdcxx.h>
+#include <memory>
namespace apache {
namespace thrift {
@@ -51,7 +51,7 @@
enum write_state_t { UNINIT, STRUCT, LIST, SET, MAP_KEY, MAP_VALUE };
public:
- TDebugProtocol(stdcxx::shared_ptr<TTransport> trans)
+ TDebugProtocol(std::shared_ptr<TTransport> trans)
: TVirtualProtocol<TDebugProtocol>(trans),
trans_(trans.get()),
string_limit_(DEFAULT_STRING_LIMIT),
@@ -138,11 +138,11 @@
*/
class TDebugProtocolFactory : public TProtocolFactory {
public:
- TDebugProtocolFactory() {}
- virtual ~TDebugProtocolFactory() {}
+ TDebugProtocolFactory() = default;
+ ~TDebugProtocolFactory() override = default;
- stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> trans) {
- return stdcxx::shared_ptr<TProtocol>(new TDebugProtocol(trans));
+ std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> trans) override {
+ return std::shared_ptr<TProtocol>(new TDebugProtocol(trans));
}
};
}
@@ -159,8 +159,8 @@
std::string ThriftDebugString(const ThriftStruct& ts) {
using namespace apache::thrift::transport;
using namespace apache::thrift::protocol;
- TMemoryBuffer* buffer = new TMemoryBuffer;
- stdcxx::shared_ptr<TTransport> trans(buffer);
+ auto* buffer = new TMemoryBuffer;
+ std::shared_ptr<TTransport> trans(buffer);
TDebugProtocol protocol(trans);
ts.write(&protocol);
@@ -178,7 +178,7 @@
using namespace apache::thrift::transport;
using namespace apache::thrift::protocol;
TMemoryBuffer* buffer = new TMemoryBuffer;
- stdcxx::shared_ptr<TTransport> trans(buffer);
+ std::shared_ptr<TTransport> trans(buffer);
TDebugProtocol protocol(trans);
// I am gross!
diff --git a/lib/cpp/src/thrift/protocol/THeaderProtocol.cpp b/lib/cpp/src/thrift/protocol/THeaderProtocol.cpp
index 2667617..6242e30 100644
--- a/lib/cpp/src/thrift/protocol/THeaderProtocol.cpp
+++ b/lib/cpp/src/thrift/protocol/THeaderProtocol.cpp
@@ -26,8 +26,7 @@
#include <limits>
-#include <boost/static_assert.hpp>
-#include <thrift/stdcxx.h>
+#include <memory>
namespace apache {
namespace thrift {
@@ -42,11 +41,11 @@
switch (protoId_) {
case T_BINARY_PROTOCOL:
- proto_ = stdcxx::make_shared<TBinaryProtocolT<THeaderTransport> >(trans_);
+ proto_ = std::make_shared<TBinaryProtocolT<THeaderTransport> >(trans_);
break;
case T_COMPACT_PROTOCOL:
- proto_ = stdcxx::make_shared<TCompactProtocolT<THeaderTransport> >(trans_);
+ proto_ = std::make_shared<TCompactProtocolT<THeaderTransport> >(trans_);
break;
default:
diff --git a/lib/cpp/src/thrift/protocol/THeaderProtocol.h b/lib/cpp/src/thrift/protocol/THeaderProtocol.h
index 8cd5017..0d50185 100644
--- a/lib/cpp/src/thrift/protocol/THeaderProtocol.h
+++ b/lib/cpp/src/thrift/protocol/THeaderProtocol.h
@@ -25,7 +25,7 @@
#include <thrift/protocol/TVirtualProtocol.h>
#include <thrift/transport/THeaderTransport.h>
-#include <thrift/stdcxx.h>
+#include <memory>
using apache::thrift::transport::THeaderTransport;
@@ -43,27 +43,27 @@
public:
void resetProtocol();
- explicit THeaderProtocol(const stdcxx::shared_ptr<TTransport>& trans,
+ explicit THeaderProtocol(const std::shared_ptr<TTransport>& trans,
uint16_t protoId = T_COMPACT_PROTOCOL)
- : TVirtualProtocol<THeaderProtocol>(stdcxx::shared_ptr<TTransport>(new THeaderTransport(trans))),
- trans_(stdcxx::dynamic_pointer_cast<THeaderTransport>(getTransport())),
+ : TVirtualProtocol<THeaderProtocol>(std::shared_ptr<TTransport>(new THeaderTransport(trans))),
+ trans_(std::dynamic_pointer_cast<THeaderTransport>(getTransport())),
protoId_(protoId) {
trans_->setProtocolId(protoId);
resetProtocol();
}
- THeaderProtocol(const stdcxx::shared_ptr<TTransport>& inTrans,
- const stdcxx::shared_ptr<TTransport>& outTrans,
+ THeaderProtocol(const std::shared_ptr<TTransport>& inTrans,
+ const std::shared_ptr<TTransport>& outTrans,
uint16_t protoId = T_COMPACT_PROTOCOL)
: TVirtualProtocol<THeaderProtocol>(
- stdcxx::shared_ptr<TTransport>(new THeaderTransport(inTrans, outTrans))),
- trans_(stdcxx::dynamic_pointer_cast<THeaderTransport>(getTransport())),
+ std::shared_ptr<TTransport>(new THeaderTransport(inTrans, outTrans))),
+ trans_(std::dynamic_pointer_cast<THeaderTransport>(getTransport())),
protoId_(protoId) {
trans_->setProtocolId(protoId);
resetProtocol();
}
- ~THeaderProtocol() {}
+ ~THeaderProtocol() override = default;
/**
* Functions to work with headers by calling into THeaderTransport
@@ -182,25 +182,25 @@
uint32_t readBinary(std::string& binary);
protected:
- stdcxx::shared_ptr<THeaderTransport> trans_;
+ std::shared_ptr<THeaderTransport> trans_;
- stdcxx::shared_ptr<TProtocol> proto_;
+ std::shared_ptr<TProtocol> proto_;
uint32_t protoId_;
};
class THeaderProtocolFactory : public TProtocolFactory {
public:
- virtual stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<transport::TTransport> trans) {
- THeaderProtocol* headerProtocol
+ std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<transport::TTransport> trans) override {
+ auto* headerProtocol
= new THeaderProtocol(trans, trans, T_BINARY_PROTOCOL);
- return stdcxx::shared_ptr<TProtocol>(headerProtocol);
+ return std::shared_ptr<TProtocol>(headerProtocol);
}
- virtual stdcxx::shared_ptr<TProtocol> getProtocol(
- stdcxx::shared_ptr<transport::TTransport> inTrans,
- stdcxx::shared_ptr<transport::TTransport> outTrans) {
- THeaderProtocol* headerProtocol = new THeaderProtocol(inTrans, outTrans, T_BINARY_PROTOCOL);
- return stdcxx::shared_ptr<TProtocol>(headerProtocol);
+ std::shared_ptr<TProtocol> getProtocol(
+ std::shared_ptr<transport::TTransport> inTrans,
+ std::shared_ptr<transport::TTransport> outTrans) override {
+ auto* headerProtocol = new THeaderProtocol(inTrans, outTrans, T_BINARY_PROTOCOL);
+ return std::shared_ptr<TProtocol>(headerProtocol);
}
};
}
diff --git a/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp b/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
index 80def7f..28d0da2 100644
--- a/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
+++ b/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
@@ -20,8 +20,6 @@
#include <thrift/protocol/TJSONProtocol.h>
#include <boost/locale.hpp>
-#include <boost/math/special_functions/fpclassify.hpp>
-#include <boost/math/special_functions/sign.hpp>
#include <cmath>
#include <limits>
@@ -49,7 +47,6 @@
static const uint8_t kJSONElemSeparator = ',';
static const uint8_t kJSONBackslash = '\\';
static const uint8_t kJSONStringDelimiter = '"';
-static const uint8_t kJSONZeroChar = '0';
static const uint8_t kJSONEscapeChar = 'u';
static const std::string kJSONEscapePrefix("\\u00");
@@ -304,9 +301,9 @@
class TJSONContext {
public:
- TJSONContext(){};
+ TJSONContext() = default;
- virtual ~TJSONContext(){};
+ virtual ~TJSONContext() = default;
/**
* Write context data to the transport. Default is to do nothing.
@@ -337,7 +334,7 @@
public:
JSONPairContext() : first_(true), colon_(true) {}
- uint32_t write(TTransport& trans) {
+ uint32_t write(TTransport& trans) override {
if (first_) {
first_ = false;
colon_ = true;
@@ -349,7 +346,7 @@
}
}
- uint32_t read(TJSONProtocol::LookaheadReader& reader) {
+ uint32_t read(TJSONProtocol::LookaheadReader& reader) override {
if (first_) {
first_ = false;
colon_ = true;
@@ -362,7 +359,7 @@
}
// Numbers must be turned into strings if they are the key part of a pair
- virtual bool escapeNum() { return colon_; }
+ bool escapeNum() override { return colon_; }
private:
bool first_;
@@ -375,7 +372,7 @@
public:
JSONListContext() : first_(true) {}
- uint32_t write(TTransport& trans) {
+ uint32_t write(TTransport& trans) override {
if (first_) {
first_ = false;
return 0;
@@ -385,7 +382,7 @@
}
}
- uint32_t read(TJSONProtocol::LookaheadReader& reader) {
+ uint32_t read(TJSONProtocol::LookaheadReader& reader) override {
if (first_) {
first_ = false;
return 0;
@@ -398,17 +395,16 @@
bool first_;
};
-TJSONProtocol::TJSONProtocol(stdcxx::shared_ptr<TTransport> ptrans)
+TJSONProtocol::TJSONProtocol(std::shared_ptr<TTransport> ptrans)
: TVirtualProtocol<TJSONProtocol>(ptrans),
trans_(ptrans.get()),
context_(new TJSONContext()),
reader_(*ptrans) {
}
-TJSONProtocol::~TJSONProtocol() {
-}
+TJSONProtocol::~TJSONProtocol() = default;
-void TJSONProtocol::pushContext(stdcxx::shared_ptr<TJSONContext> c) {
+void TJSONProtocol::pushContext(std::shared_ptr<TJSONContext> c) {
contexts_.push(context_);
context_ = c;
}
@@ -478,10 +474,10 @@
result += 2; // For quotes
trans_->write(&kJSONStringDelimiter, 1);
uint8_t b[4];
- const uint8_t* bytes = (const uint8_t*)str.c_str();
+ const auto* bytes = (const uint8_t*)str.c_str();
if (str.length() > (std::numeric_limits<uint32_t>::max)())
throw TProtocolException(TProtocolException::SIZE_LIMIT);
- uint32_t len = static_cast<uint32_t>(str.length());
+ auto len = static_cast<uint32_t>(str.length());
while (len >= 3) {
// Encode 3 bytes at a time
base64_encode(bytes, 3, b);
@@ -539,9 +535,9 @@
std::string val;
bool special = false;
- switch (boost::math::fpclassify(num)) {
+ switch (std::fpclassify(num)) {
case FP_INFINITE:
- if (boost::math::signbit(num)) {
+ if (std::signbit(num)) {
val = kThriftNegativeInfinity;
} else {
val = kThriftInfinity;
@@ -576,7 +572,7 @@
uint32_t TJSONProtocol::writeJSONObjectStart() {
uint32_t result = context_->write(*trans_);
trans_->write(&kJSONObjectStart, 1);
- pushContext(stdcxx::shared_ptr<TJSONContext>(new JSONPairContext()));
+ pushContext(std::shared_ptr<TJSONContext>(new JSONPairContext()));
return result + 1;
}
@@ -589,7 +585,7 @@
uint32_t TJSONProtocol::writeJSONArrayStart() {
uint32_t result = context_->write(*trans_);
trans_->write(&kJSONArrayStart, 1);
- pushContext(stdcxx::shared_ptr<TJSONContext>(new JSONListContext()));
+ pushContext(std::shared_ptr<TJSONContext>(new JSONListContext()));
return result + 1;
}
@@ -799,10 +795,10 @@
uint32_t TJSONProtocol::readJSONBase64(std::string& str) {
std::string tmp;
uint32_t result = readJSONString(tmp);
- uint8_t* b = (uint8_t*)tmp.c_str();
+ auto* b = (uint8_t*)tmp.c_str();
if (tmp.length() > (std::numeric_limits<uint32_t>::max)())
throw TProtocolException(TProtocolException::SIZE_LIMIT);
- uint32_t len = static_cast<uint32_t>(tmp.length());
+ auto len = static_cast<uint32_t>(tmp.length());
str.clear();
// Ignore padding
if (len >= 2) {
@@ -899,7 +895,7 @@
}
try {
num = fromString<double>(str);
- } catch (std::runtime_error& e) {
+ } catch (const std::runtime_error&) {
throw TProtocolException(TProtocolException::INVALID_DATA,
"Expected numeric value; got \"" + str + "\"");
}
@@ -912,7 +908,7 @@
result += readJSONNumericChars(str);
try {
num = fromString<double>(str);
- } catch (std::runtime_error& e) {
+ } catch (const std::runtime_error&) {
throw TProtocolException(TProtocolException::INVALID_DATA,
"Expected numeric value; got \"" + str + "\"");
}
@@ -923,7 +919,7 @@
uint32_t TJSONProtocol::readJSONObjectStart() {
uint32_t result = context_->read(reader_);
result += readJSONSyntaxChar(kJSONObjectStart);
- pushContext(stdcxx::shared_ptr<TJSONContext>(new JSONPairContext()));
+ pushContext(std::shared_ptr<TJSONContext>(new JSONPairContext()));
return result;
}
@@ -936,7 +932,7 @@
uint32_t TJSONProtocol::readJSONArrayStart() {
uint32_t result = context_->read(reader_);
result += readJSONSyntaxChar(kJSONArrayStart);
- pushContext(stdcxx::shared_ptr<TJSONContext>(new JSONListContext()));
+ pushContext(std::shared_ptr<TJSONContext>(new JSONListContext()));
return result;
}
@@ -950,7 +946,7 @@
TMessageType& messageType,
int32_t& seqid) {
uint32_t result = readJSONArrayStart();
- uint64_t tmpVal = 0;
+ int64_t tmpVal = 0;
result += readJSONInteger(tmpVal);
if (tmpVal != kThriftVersion1) {
throw TProtocolException(TProtocolException::BAD_VERSION, "Message contained bad version.");
@@ -959,8 +955,9 @@
result += readJSONInteger(tmpVal);
messageType = (TMessageType)tmpVal;
result += readJSONInteger(tmpVal);
- if (tmpVal > static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
- throw TProtocolException(TProtocolException::SIZE_LIMIT);
+ if (tmpVal > (std::numeric_limits<int32_t>::max)() ||
+ tmpVal < (std::numeric_limits<int32_t>::min)())
+ throw TProtocolException(TProtocolException::INVALID_DATA, "sequence id is not int32_t");
seqid = static_cast<int32_t>(tmpVal);
return result;
}
@@ -1066,7 +1063,7 @@
// readByte() must be handled properly because boost::lexical cast sees int8_t
// as a text type instead of an integer type
uint32_t TJSONProtocol::readByte(int8_t& byte) {
- int16_t tmp = (int16_t)byte;
+ auto tmp = (int16_t)byte;
uint32_t result = readJSONInteger(tmp);
assert(tmp < 256);
byte = (int8_t)tmp;
diff --git a/lib/cpp/src/thrift/protocol/TJSONProtocol.h b/lib/cpp/src/thrift/protocol/TJSONProtocol.h
index 16dff56..420995e 100644
--- a/lib/cpp/src/thrift/protocol/TJSONProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TJSONProtocol.h
@@ -96,12 +96,12 @@
*/
class TJSONProtocol : public TVirtualProtocol<TJSONProtocol> {
public:
- TJSONProtocol(stdcxx::shared_ptr<TTransport> ptrans);
+ TJSONProtocol(std::shared_ptr<TTransport> ptrans);
- ~TJSONProtocol();
+ ~TJSONProtocol() override;
private:
- void pushContext(stdcxx::shared_ptr<TJSONContext> c);
+ void pushContext(std::shared_ptr<TJSONContext> c);
void popContext();
@@ -248,7 +248,7 @@
class LookaheadReader {
public:
- LookaheadReader(TTransport& trans) : trans_(&trans), hasData_(false) {}
+ LookaheadReader(TTransport& trans) : trans_(&trans), hasData_(false), data_(0) {}
uint8_t read() {
if (hasData_) {
@@ -276,8 +276,8 @@
private:
TTransport* trans_;
- std::stack<stdcxx::shared_ptr<TJSONContext> > contexts_;
- stdcxx::shared_ptr<TJSONContext> context_;
+ std::stack<std::shared_ptr<TJSONContext> > contexts_;
+ std::shared_ptr<TJSONContext> context_;
LookaheadReader reader_;
};
@@ -286,12 +286,12 @@
*/
class TJSONProtocolFactory : public TProtocolFactory {
public:
- TJSONProtocolFactory() {}
+ TJSONProtocolFactory() = default;
- virtual ~TJSONProtocolFactory() {}
+ ~TJSONProtocolFactory() override = default;
- stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> trans) {
- return stdcxx::shared_ptr<TProtocol>(new TJSONProtocol(trans));
+ std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> trans) override {
+ return std::shared_ptr<TProtocol>(new TJSONProtocol(trans));
}
};
}
@@ -308,8 +308,8 @@
std::string ThriftJSONString(const ThriftStruct& ts) {
using namespace apache::thrift::transport;
using namespace apache::thrift::protocol;
- TMemoryBuffer* buffer = new TMemoryBuffer;
- stdcxx::shared_ptr<TTransport> trans(buffer);
+ auto* buffer = new TMemoryBuffer;
+ std::shared_ptr<TTransport> trans(buffer);
TJSONProtocol protocol(trans);
ts.write(&protocol);
diff --git a/lib/cpp/src/thrift/protocol/TMultiplexedProtocol.h b/lib/cpp/src/thrift/protocol/TMultiplexedProtocol.h
index dd7e88f..0dc9605 100644
--- a/lib/cpp/src/thrift/protocol/TMultiplexedProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TMultiplexedProtocol.h
@@ -25,7 +25,7 @@
namespace apache {
namespace thrift {
namespace protocol {
-using stdcxx::shared_ptr;
+using std::shared_ptr;
/**
* <code>TMultiplexedProtocol</code> is a protocol-independent concrete decorator
@@ -69,7 +69,7 @@
*/
TMultiplexedProtocol(shared_ptr<TProtocol> _protocol, const std::string& _serviceName)
: TProtocolDecorator(_protocol), serviceName(_serviceName), separator(":") {}
- virtual ~TMultiplexedProtocol() {}
+ ~TMultiplexedProtocol() override = default;
/**
* Prepends the service name to the function name, separated by TMultiplexedProtocol::SEPARATOR.
@@ -82,7 +82,7 @@
*/
uint32_t writeMessageBegin_virt(const std::string& _name,
const TMessageType _type,
- const int32_t _seqid);
+ const int32_t _seqid) override;
private:
const std::string serviceName;
diff --git a/lib/cpp/src/thrift/protocol/TProtocol.cpp b/lib/cpp/src/thrift/protocol/TProtocol.cpp
index c378aca..b460455 100644
--- a/lib/cpp/src/thrift/protocol/TProtocol.cpp
+++ b/lib/cpp/src/thrift/protocol/TProtocol.cpp
@@ -23,11 +23,11 @@
namespace thrift {
namespace protocol {
-TProtocol::~TProtocol() {}
+TProtocol::~TProtocol() = default;
uint32_t TProtocol::skip_virt(TType type) {
return ::apache::thrift::protocol::skip(*this, type);
}
-TProtocolFactory::~TProtocolFactory() {}
+TProtocolFactory::~TProtocolFactory() = default;
}}} // apache::thrift::protocol
diff --git a/lib/cpp/src/thrift/protocol/TProtocol.h b/lib/cpp/src/thrift/protocol/TProtocol.h
index 6e2ddd2..df9c5c3 100644
--- a/lib/cpp/src/thrift/protocol/TProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TProtocol.h
@@ -28,8 +28,7 @@
#include <thrift/transport/TTransport.h>
#include <thrift/protocol/TProtocolException.h>
-#include <thrift/stdcxx.h>
-#include <boost/static_assert.hpp>
+#include <memory>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
@@ -48,7 +47,7 @@
// http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
template <typename To, typename From>
static inline To bitwise_cast(From from) {
- BOOST_STATIC_ASSERT(sizeof(From) == sizeof(To));
+ static_assert(sizeof(From) == sizeof(To), "sizeof(From) == sizeof(To)");
// BAD!!! These are all broken with -O2.
//return *reinterpret_cast<To*>(&from); // BAD!!!
@@ -89,15 +88,18 @@
# define __THRIFT_LITTLE_ENDIAN LITTLE_ENDIAN
# define __THRIFT_BIG_ENDIAN BIG_ENDIAN
# else
-# include <boost/config.hpp>
-# include <boost/detail/endian.hpp>
-# define __THRIFT_BYTE_ORDER BOOST_BYTE_ORDER
+# include <boost/predef/other/endian.h>
+# if BOOST_ENDIAN_BIG_BYTE
+# define __THRIFT_BYTE_ORDER 4321
+# define __THRIFT_LITTLE_ENDIAN 0
+# define __THRIFT_BIG_ENDIAN __THRIFT_BYTE_ORDER
+# elif BOOST_ENDIAN_LITTLE_BYTE
+# define __THRIFT_BYTE_ORDER 1234
+# define __THRIFT_LITTLE_ENDIAN __THRIFT_BYTE_ORDER
+# define __THRIFT_BIG_ENDIAN 0
+# endif
# ifdef BOOST_LITTLE_ENDIAN
-# define __THRIFT_LITTLE_ENDIAN __THRIFT_BYTE_ORDER
-# define __THRIFT_BIG_ENDIAN 0
# else
-# define __THRIFT_LITTLE_ENDIAN 0
-# define __THRIFT_BIG_ENDIAN __THRIFT_BYTE_ORDER
# endif
# endif
#endif
@@ -550,12 +552,12 @@
}
virtual uint32_t skip_virt(TType type);
- inline stdcxx::shared_ptr<TTransport> getTransport() { return ptrans_; }
+ inline std::shared_ptr<TTransport> getTransport() { return ptrans_; }
// TODO: remove these two calls, they are for backwards
// compatibility
- inline stdcxx::shared_ptr<TTransport> getInputTransport() { return ptrans_; }
- inline stdcxx::shared_ptr<TTransport> getOutputTransport() { return ptrans_; }
+ inline std::shared_ptr<TTransport> getInputTransport() { return ptrans_; }
+ inline std::shared_ptr<TTransport> getOutputTransport() { return ptrans_; }
// input and output recursion depth are kept separate so that one protocol
// can be used concurrently for both input and output.
@@ -577,14 +579,14 @@
void setRecurisionLimit(uint32_t depth) {recursion_limit_ = depth;}
protected:
- TProtocol(stdcxx::shared_ptr<TTransport> ptrans)
+ TProtocol(std::shared_ptr<TTransport> ptrans)
: ptrans_(ptrans), input_recursion_depth_(0), output_recursion_depth_(0), recursion_limit_(DEFAULT_RECURSION_LIMIT)
{}
- stdcxx::shared_ptr<TTransport> ptrans_;
+ std::shared_ptr<TTransport> ptrans_;
private:
- TProtocol() {}
+ TProtocol() = default;
uint32_t input_recursion_depth_;
uint32_t output_recursion_depth_;
uint32_t recursion_limit_;
@@ -595,13 +597,13 @@
*/
class TProtocolFactory {
public:
- TProtocolFactory() {}
+ TProtocolFactory() = default;
virtual ~TProtocolFactory();
- virtual stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> trans) = 0;
- virtual stdcxx::shared_ptr<TProtocol> getProtocol(stdcxx::shared_ptr<TTransport> inTrans,
- stdcxx::shared_ptr<TTransport> outTrans) {
+ virtual std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> trans) = 0;
+ virtual std::shared_ptr<TProtocol> getProtocol(std::shared_ptr<TTransport> inTrans,
+ std::shared_ptr<TTransport> outTrans) {
(void)outTrans;
return getProtocol(inTrans);
}
diff --git a/lib/cpp/src/thrift/protocol/TProtocolDecorator.h b/lib/cpp/src/thrift/protocol/TProtocolDecorator.h
index a353b79..5258159 100644
--- a/lib/cpp/src/thrift/protocol/TProtocolDecorator.h
+++ b/lib/cpp/src/thrift/protocol/TProtocolDecorator.h
@@ -21,12 +21,12 @@
#define THRIFT_TPROTOCOLDECORATOR_H_ 1
#include <thrift/protocol/TProtocol.h>
-#include <thrift/stdcxx.h>
+#include <memory>
namespace apache {
namespace thrift {
namespace protocol {
-using stdcxx::shared_ptr;
+using std::shared_ptr;
/**
* <code>TProtocolDecorator</code> forwards all requests to an enclosed
@@ -39,107 +39,107 @@
*/
class TProtocolDecorator : public TProtocol {
public:
- virtual ~TProtocolDecorator() {}
+ ~TProtocolDecorator() override = default;
// Desc: Initializes the protocol decorator object.
TProtocolDecorator(shared_ptr<TProtocol> proto)
: TProtocol(proto->getTransport()), protocol(proto) {}
- virtual uint32_t writeMessageBegin_virt(const std::string& name,
+ uint32_t writeMessageBegin_virt(const std::string& name,
const TMessageType messageType,
- const int32_t seqid) {
+ const int32_t seqid) override {
return protocol->writeMessageBegin(name, messageType, seqid);
}
- virtual uint32_t writeMessageEnd_virt() { return protocol->writeMessageEnd(); }
- virtual uint32_t writeStructBegin_virt(const char* name) {
+ uint32_t writeMessageEnd_virt() override { return protocol->writeMessageEnd(); }
+ uint32_t writeStructBegin_virt(const char* name) override {
return protocol->writeStructBegin(name);
}
- virtual uint32_t writeStructEnd_virt() { return protocol->writeStructEnd(); }
+ uint32_t writeStructEnd_virt() override { return protocol->writeStructEnd(); }
- virtual uint32_t writeFieldBegin_virt(const char* name,
+ uint32_t writeFieldBegin_virt(const char* name,
const TType fieldType,
- const int16_t fieldId) {
+ const int16_t fieldId) override {
return protocol->writeFieldBegin(name, fieldType, fieldId);
}
- virtual uint32_t writeFieldEnd_virt() { return protocol->writeFieldEnd(); }
- virtual uint32_t writeFieldStop_virt() { return protocol->writeFieldStop(); }
+ uint32_t writeFieldEnd_virt() override { return protocol->writeFieldEnd(); }
+ uint32_t writeFieldStop_virt() override { return protocol->writeFieldStop(); }
- virtual uint32_t writeMapBegin_virt(const TType keyType,
+ uint32_t writeMapBegin_virt(const TType keyType,
const TType valType,
- const uint32_t size) {
+ const uint32_t size) override {
return protocol->writeMapBegin(keyType, valType, size);
}
- virtual uint32_t writeMapEnd_virt() { return protocol->writeMapEnd(); }
+ uint32_t writeMapEnd_virt() override { return protocol->writeMapEnd(); }
- virtual uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) {
+ uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) override {
return protocol->writeListBegin(elemType, size);
}
- virtual uint32_t writeListEnd_virt() { return protocol->writeListEnd(); }
+ uint32_t writeListEnd_virt() override { return protocol->writeListEnd(); }
- virtual uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) {
+ uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) override {
return protocol->writeSetBegin(elemType, size);
}
- virtual uint32_t writeSetEnd_virt() { return protocol->writeSetEnd(); }
+ uint32_t writeSetEnd_virt() override { return protocol->writeSetEnd(); }
- virtual uint32_t writeBool_virt(const bool value) { return protocol->writeBool(value); }
- virtual uint32_t writeByte_virt(const int8_t byte) { return protocol->writeByte(byte); }
- virtual uint32_t writeI16_virt(const int16_t i16) { return protocol->writeI16(i16); }
- virtual uint32_t writeI32_virt(const int32_t i32) { return protocol->writeI32(i32); }
- virtual uint32_t writeI64_virt(const int64_t i64) { return protocol->writeI64(i64); }
+ uint32_t writeBool_virt(const bool value) override { return protocol->writeBool(value); }
+ uint32_t writeByte_virt(const int8_t byte) override { return protocol->writeByte(byte); }
+ uint32_t writeI16_virt(const int16_t i16) override { return protocol->writeI16(i16); }
+ uint32_t writeI32_virt(const int32_t i32) override { return protocol->writeI32(i32); }
+ uint32_t writeI64_virt(const int64_t i64) override { return protocol->writeI64(i64); }
- virtual uint32_t writeDouble_virt(const double dub) { return protocol->writeDouble(dub); }
- virtual uint32_t writeString_virt(const std::string& str) { return protocol->writeString(str); }
- virtual uint32_t writeBinary_virt(const std::string& str) { return protocol->writeBinary(str); }
+ uint32_t writeDouble_virt(const double dub) override { return protocol->writeDouble(dub); }
+ uint32_t writeString_virt(const std::string& str) override { return protocol->writeString(str); }
+ uint32_t writeBinary_virt(const std::string& str) override { return protocol->writeBinary(str); }
- virtual uint32_t readMessageBegin_virt(std::string& name,
+ uint32_t readMessageBegin_virt(std::string& name,
TMessageType& messageType,
- int32_t& seqid) {
+ int32_t& seqid) override {
return protocol->readMessageBegin(name, messageType, seqid);
}
- virtual uint32_t readMessageEnd_virt() { return protocol->readMessageEnd(); }
+ uint32_t readMessageEnd_virt() override { return protocol->readMessageEnd(); }
- virtual uint32_t readStructBegin_virt(std::string& name) {
+ uint32_t readStructBegin_virt(std::string& name) override {
return protocol->readStructBegin(name);
}
- virtual uint32_t readStructEnd_virt() { return protocol->readStructEnd(); }
+ uint32_t readStructEnd_virt() override { return protocol->readStructEnd(); }
- virtual uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) {
+ uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) override {
return protocol->readFieldBegin(name, fieldType, fieldId);
}
- virtual uint32_t readFieldEnd_virt() { return protocol->readFieldEnd(); }
+ uint32_t readFieldEnd_virt() override { return protocol->readFieldEnd(); }
- virtual uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) {
+ uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) override {
return protocol->readMapBegin(keyType, valType, size);
}
- virtual uint32_t readMapEnd_virt() { return protocol->readMapEnd(); }
+ uint32_t readMapEnd_virt() override { return protocol->readMapEnd(); }
- virtual uint32_t readListBegin_virt(TType& elemType, uint32_t& size) {
+ uint32_t readListBegin_virt(TType& elemType, uint32_t& size) override {
return protocol->readListBegin(elemType, size);
}
- virtual uint32_t readListEnd_virt() { return protocol->readListEnd(); }
+ uint32_t readListEnd_virt() override { return protocol->readListEnd(); }
- virtual uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) {
+ uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) override {
return protocol->readSetBegin(elemType, size);
}
- virtual uint32_t readSetEnd_virt() { return protocol->readSetEnd(); }
+ uint32_t readSetEnd_virt() override { return protocol->readSetEnd(); }
- virtual uint32_t readBool_virt(bool& value) { return protocol->readBool(value); }
- virtual uint32_t readBool_virt(std::vector<bool>::reference value) {
+ uint32_t readBool_virt(bool& value) override { return protocol->readBool(value); }
+ uint32_t readBool_virt(std::vector<bool>::reference value) override {
return protocol->readBool(value);
}
- virtual uint32_t readByte_virt(int8_t& byte) { return protocol->readByte(byte); }
+ uint32_t readByte_virt(int8_t& byte) override { return protocol->readByte(byte); }
- virtual uint32_t readI16_virt(int16_t& i16) { return protocol->readI16(i16); }
- virtual uint32_t readI32_virt(int32_t& i32) { return protocol->readI32(i32); }
- virtual uint32_t readI64_virt(int64_t& i64) { return protocol->readI64(i64); }
+ uint32_t readI16_virt(int16_t& i16) override { return protocol->readI16(i16); }
+ uint32_t readI32_virt(int32_t& i32) override { return protocol->readI32(i32); }
+ uint32_t readI64_virt(int64_t& i64) override { return protocol->readI64(i64); }
- virtual uint32_t readDouble_virt(double& dub) { return protocol->readDouble(dub); }
+ uint32_t readDouble_virt(double& dub) override { return protocol->readDouble(dub); }
- virtual uint32_t readString_virt(std::string& str) { return protocol->readString(str); }
- virtual uint32_t readBinary_virt(std::string& str) { return protocol->readBinary(str); }
+ uint32_t readString_virt(std::string& str) override { return protocol->readString(str); }
+ uint32_t readBinary_virt(std::string& str) override { return protocol->readBinary(str); }
private:
shared_ptr<TProtocol> protocol;
diff --git a/lib/cpp/src/thrift/protocol/TProtocolException.h b/lib/cpp/src/thrift/protocol/TProtocolException.h
index 6e536b4..3d44365 100644
--- a/lib/cpp/src/thrift/protocol/TProtocolException.h
+++ b/lib/cpp/src/thrift/protocol/TProtocolException.h
@@ -59,7 +59,7 @@
TProtocolException(TProtocolExceptionType type, const std::string& message)
: apache::thrift::TException(message), type_(type) {}
- virtual ~TProtocolException() throw() {}
+ ~TProtocolException() noexcept override = default;
/**
* Returns an error code that provides information about the type of error
@@ -69,7 +69,7 @@
*/
TProtocolExceptionType getType() const { return type_; }
- virtual const char* what() const throw() {
+ const char* what() const noexcept override {
if (message_.empty()) {
switch (type_) {
case UNKNOWN:
diff --git a/lib/cpp/src/thrift/protocol/TProtocolTap.h b/lib/cpp/src/thrift/protocol/TProtocolTap.h
index 176d4fd..d000ba6 100644
--- a/lib/cpp/src/thrift/protocol/TProtocolTap.h
+++ b/lib/cpp/src/thrift/protocol/TProtocolTap.h
@@ -36,7 +36,7 @@
*/
class TProtocolTap : public TVirtualProtocol<TProtocolTap> {
public:
- TProtocolTap(stdcxx::shared_ptr<TProtocol> source, stdcxx::shared_ptr<TProtocol> sink)
+ TProtocolTap(std::shared_ptr<TProtocol> source, std::shared_ptr<TProtocol> sink)
: TVirtualProtocol<TProtocolTap>(source->getTransport()), source_(source), sink_(sink) {}
uint32_t readMessageBegin(std::string& name, TMessageType& messageType, int32_t& seqid) {
@@ -167,8 +167,8 @@
}
private:
- stdcxx::shared_ptr<TProtocol> source_;
- stdcxx::shared_ptr<TProtocol> sink_;
+ std::shared_ptr<TProtocol> source_;
+ std::shared_ptr<TProtocol> sink_;
};
}
}
diff --git a/lib/cpp/src/thrift/protocol/TVirtualProtocol.h b/lib/cpp/src/thrift/protocol/TVirtualProtocol.h
index 628b494..b7fe929 100644
--- a/lib/cpp/src/thrift/protocol/TVirtualProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TVirtualProtocol.h
@@ -301,7 +301,7 @@
uint32_t skip(TType type) { return ::apache::thrift::protocol::skip(*this, type); }
protected:
- TProtocolDefaults(stdcxx::shared_ptr<TTransport> ptrans) : TProtocol(ptrans) {}
+ TProtocolDefaults(std::shared_ptr<TTransport> ptrans) : TProtocol(ptrans) {}
};
/**
@@ -315,81 +315,81 @@
* Writing functions.
*/
- virtual uint32_t writeMessageBegin_virt(const std::string& name,
+ uint32_t writeMessageBegin_virt(const std::string& name,
const TMessageType messageType,
- const int32_t seqid) {
+ const int32_t seqid) override {
return static_cast<Protocol_*>(this)->writeMessageBegin(name, messageType, seqid);
}
- virtual uint32_t writeMessageEnd_virt() {
+ uint32_t writeMessageEnd_virt() override {
return static_cast<Protocol_*>(this)->writeMessageEnd();
}
- virtual uint32_t writeStructBegin_virt(const char* name) {
+ uint32_t writeStructBegin_virt(const char* name) override {
return static_cast<Protocol_*>(this)->writeStructBegin(name);
}
- virtual uint32_t writeStructEnd_virt() { return static_cast<Protocol_*>(this)->writeStructEnd(); }
+ uint32_t writeStructEnd_virt() override { return static_cast<Protocol_*>(this)->writeStructEnd(); }
- virtual uint32_t writeFieldBegin_virt(const char* name,
+ uint32_t writeFieldBegin_virt(const char* name,
const TType fieldType,
- const int16_t fieldId) {
+ const int16_t fieldId) override {
return static_cast<Protocol_*>(this)->writeFieldBegin(name, fieldType, fieldId);
}
- virtual uint32_t writeFieldEnd_virt() { return static_cast<Protocol_*>(this)->writeFieldEnd(); }
+ uint32_t writeFieldEnd_virt() override { return static_cast<Protocol_*>(this)->writeFieldEnd(); }
- virtual uint32_t writeFieldStop_virt() { return static_cast<Protocol_*>(this)->writeFieldStop(); }
+ uint32_t writeFieldStop_virt() override { return static_cast<Protocol_*>(this)->writeFieldStop(); }
- virtual uint32_t writeMapBegin_virt(const TType keyType,
+ uint32_t writeMapBegin_virt(const TType keyType,
const TType valType,
- const uint32_t size) {
+ const uint32_t size) override {
return static_cast<Protocol_*>(this)->writeMapBegin(keyType, valType, size);
}
- virtual uint32_t writeMapEnd_virt() { return static_cast<Protocol_*>(this)->writeMapEnd(); }
+ uint32_t writeMapEnd_virt() override { return static_cast<Protocol_*>(this)->writeMapEnd(); }
- virtual uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) {
+ uint32_t writeListBegin_virt(const TType elemType, const uint32_t size) override {
return static_cast<Protocol_*>(this)->writeListBegin(elemType, size);
}
- virtual uint32_t writeListEnd_virt() { return static_cast<Protocol_*>(this)->writeListEnd(); }
+ uint32_t writeListEnd_virt() override { return static_cast<Protocol_*>(this)->writeListEnd(); }
- virtual uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) {
+ uint32_t writeSetBegin_virt(const TType elemType, const uint32_t size) override {
return static_cast<Protocol_*>(this)->writeSetBegin(elemType, size);
}
- virtual uint32_t writeSetEnd_virt() { return static_cast<Protocol_*>(this)->writeSetEnd(); }
+ uint32_t writeSetEnd_virt() override { return static_cast<Protocol_*>(this)->writeSetEnd(); }
- virtual uint32_t writeBool_virt(const bool value) {
+ uint32_t writeBool_virt(const bool value) override {
return static_cast<Protocol_*>(this)->writeBool(value);
}
- virtual uint32_t writeByte_virt(const int8_t byte) {
+ uint32_t writeByte_virt(const int8_t byte) override {
return static_cast<Protocol_*>(this)->writeByte(byte);
}
- virtual uint32_t writeI16_virt(const int16_t i16) {
+ uint32_t writeI16_virt(const int16_t i16) override {
return static_cast<Protocol_*>(this)->writeI16(i16);
}
- virtual uint32_t writeI32_virt(const int32_t i32) {
+ uint32_t writeI32_virt(const int32_t i32) override {
return static_cast<Protocol_*>(this)->writeI32(i32);
}
- virtual uint32_t writeI64_virt(const int64_t i64) {
+ uint32_t writeI64_virt(const int64_t i64) override {
return static_cast<Protocol_*>(this)->writeI64(i64);
}
- virtual uint32_t writeDouble_virt(const double dub) {
+ uint32_t writeDouble_virt(const double dub) override {
return static_cast<Protocol_*>(this)->writeDouble(dub);
}
- virtual uint32_t writeString_virt(const std::string& str) {
+ uint32_t writeString_virt(const std::string& str) override {
return static_cast<Protocol_*>(this)->writeString(str);
}
- virtual uint32_t writeBinary_virt(const std::string& str) {
+ uint32_t writeBinary_virt(const std::string& str) override {
return static_cast<Protocol_*>(this)->writeBinary(str);
}
@@ -397,81 +397,81 @@
* Reading functions
*/
- virtual uint32_t readMessageBegin_virt(std::string& name,
+ uint32_t readMessageBegin_virt(std::string& name,
TMessageType& messageType,
- int32_t& seqid) {
+ int32_t& seqid) override {
return static_cast<Protocol_*>(this)->readMessageBegin(name, messageType, seqid);
}
- virtual uint32_t readMessageEnd_virt() { return static_cast<Protocol_*>(this)->readMessageEnd(); }
+ uint32_t readMessageEnd_virt() override { return static_cast<Protocol_*>(this)->readMessageEnd(); }
- virtual uint32_t readStructBegin_virt(std::string& name) {
+ uint32_t readStructBegin_virt(std::string& name) override {
return static_cast<Protocol_*>(this)->readStructBegin(name);
}
- virtual uint32_t readStructEnd_virt() { return static_cast<Protocol_*>(this)->readStructEnd(); }
+ uint32_t readStructEnd_virt() override { return static_cast<Protocol_*>(this)->readStructEnd(); }
- virtual uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) {
+ uint32_t readFieldBegin_virt(std::string& name, TType& fieldType, int16_t& fieldId) override {
return static_cast<Protocol_*>(this)->readFieldBegin(name, fieldType, fieldId);
}
- virtual uint32_t readFieldEnd_virt() { return static_cast<Protocol_*>(this)->readFieldEnd(); }
+ uint32_t readFieldEnd_virt() override { return static_cast<Protocol_*>(this)->readFieldEnd(); }
- virtual uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) {
+ uint32_t readMapBegin_virt(TType& keyType, TType& valType, uint32_t& size) override {
return static_cast<Protocol_*>(this)->readMapBegin(keyType, valType, size);
}
- virtual uint32_t readMapEnd_virt() { return static_cast<Protocol_*>(this)->readMapEnd(); }
+ uint32_t readMapEnd_virt() override { return static_cast<Protocol_*>(this)->readMapEnd(); }
- virtual uint32_t readListBegin_virt(TType& elemType, uint32_t& size) {
+ uint32_t readListBegin_virt(TType& elemType, uint32_t& size) override {
return static_cast<Protocol_*>(this)->readListBegin(elemType, size);
}
- virtual uint32_t readListEnd_virt() { return static_cast<Protocol_*>(this)->readListEnd(); }
+ uint32_t readListEnd_virt() override { return static_cast<Protocol_*>(this)->readListEnd(); }
- virtual uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) {
+ uint32_t readSetBegin_virt(TType& elemType, uint32_t& size) override {
return static_cast<Protocol_*>(this)->readSetBegin(elemType, size);
}
- virtual uint32_t readSetEnd_virt() { return static_cast<Protocol_*>(this)->readSetEnd(); }
+ uint32_t readSetEnd_virt() override { return static_cast<Protocol_*>(this)->readSetEnd(); }
- virtual uint32_t readBool_virt(bool& value) {
+ uint32_t readBool_virt(bool& value) override {
return static_cast<Protocol_*>(this)->readBool(value);
}
- virtual uint32_t readBool_virt(std::vector<bool>::reference value) {
+ uint32_t readBool_virt(std::vector<bool>::reference value) override {
return static_cast<Protocol_*>(this)->readBool(value);
}
- virtual uint32_t readByte_virt(int8_t& byte) {
+ uint32_t readByte_virt(int8_t& byte) override {
return static_cast<Protocol_*>(this)->readByte(byte);
}
- virtual uint32_t readI16_virt(int16_t& i16) {
+ uint32_t readI16_virt(int16_t& i16) override {
return static_cast<Protocol_*>(this)->readI16(i16);
}
- virtual uint32_t readI32_virt(int32_t& i32) {
+ uint32_t readI32_virt(int32_t& i32) override {
return static_cast<Protocol_*>(this)->readI32(i32);
}
- virtual uint32_t readI64_virt(int64_t& i64) {
+ uint32_t readI64_virt(int64_t& i64) override {
return static_cast<Protocol_*>(this)->readI64(i64);
}
- virtual uint32_t readDouble_virt(double& dub) {
+ uint32_t readDouble_virt(double& dub) override {
return static_cast<Protocol_*>(this)->readDouble(dub);
}
- virtual uint32_t readString_virt(std::string& str) {
+ uint32_t readString_virt(std::string& str) override {
return static_cast<Protocol_*>(this)->readString(str);
}
- virtual uint32_t readBinary_virt(std::string& str) {
+ uint32_t readBinary_virt(std::string& str) override {
return static_cast<Protocol_*>(this)->readBinary(str);
}
- virtual uint32_t skip_virt(TType type) { return static_cast<Protocol_*>(this)->skip(type); }
+ uint32_t skip_virt(TType type) override { return static_cast<Protocol_*>(this)->skip(type); }
/*
* Provide a default skip() implementation that uses non-virtual read
@@ -484,7 +484,7 @@
* correct parent implementation, if desired.
*/
uint32_t skip(TType type) {
- Protocol_* const prot = static_cast<Protocol_*>(this);
+ auto* const prot = static_cast<Protocol_*>(this);
return ::apache::thrift::protocol::skip(*prot, type);
}
@@ -504,7 +504,7 @@
using Super_::readBool; // so we don't hide readBool(bool&)
protected:
- TVirtualProtocol(stdcxx::shared_ptr<TTransport> ptrans) : Super_(ptrans) {}
+ TVirtualProtocol(std::shared_ptr<TTransport> ptrans) : Super_(ptrans) {}
};
}
}
diff --git a/lib/cpp/src/thrift/qt/TQIODeviceTransport.cpp b/lib/cpp/src/thrift/qt/TQIODeviceTransport.cpp
index 0e46f11..1537fc6 100644
--- a/lib/cpp/src/thrift/qt/TQIODeviceTransport.cpp
+++ b/lib/cpp/src/thrift/qt/TQIODeviceTransport.cpp
@@ -23,12 +23,12 @@
#include <QIODevice>
#include <thrift/transport/TBufferTransports.h>
-#include <thrift/stdcxx.h>
+#include <memory>
namespace apache {
namespace thrift {
-using stdcxx::shared_ptr;
+using std::shared_ptr;
namespace transport {
@@ -46,7 +46,7 @@
}
}
-bool TQIODeviceTransport::isOpen() {
+bool TQIODeviceTransport::isOpen() const {
return dev_->isOpen();
}
@@ -157,7 +157,7 @@
uint8_t* TQIODeviceTransport::borrow(uint8_t* buf, uint32_t* len) {
(void)buf;
(void)len;
- return NULL;
+ return nullptr;
}
void TQIODeviceTransport::consume(uint32_t len) {
diff --git a/lib/cpp/src/thrift/qt/TQIODeviceTransport.h b/lib/cpp/src/thrift/qt/TQIODeviceTransport.h
index 9087f2c..a3b511d 100644
--- a/lib/cpp/src/thrift/qt/TQIODeviceTransport.h
+++ b/lib/cpp/src/thrift/qt/TQIODeviceTransport.h
@@ -20,7 +20,7 @@
#ifndef _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_
#define _THRIFT_ASYNC_TQIODEVICE_TRANSPORT_H_ 1
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/transport/TVirtualTransport.h>
@@ -36,13 +36,13 @@
class TQIODeviceTransport
: public apache::thrift::transport::TVirtualTransport<TQIODeviceTransport> {
public:
- explicit TQIODeviceTransport(stdcxx::shared_ptr<QIODevice> dev);
- virtual ~TQIODeviceTransport();
+ explicit TQIODeviceTransport(std::shared_ptr<QIODevice> dev);
+ ~TQIODeviceTransport() override;
- void open();
- bool isOpen();
- bool peek();
- void close();
+ void open() override;
+ bool isOpen() const override;
+ bool peek() override;
+ void close() override;
uint32_t readAll(uint8_t* buf, uint32_t len);
uint32_t read(uint8_t* buf, uint32_t len);
@@ -50,7 +50,7 @@
void write(const uint8_t* buf, uint32_t len);
uint32_t write_partial(const uint8_t* buf, uint32_t len);
- void flush();
+ void flush() override;
uint8_t* borrow(uint8_t* buf, uint32_t* len);
void consume(uint32_t len);
@@ -59,7 +59,7 @@
TQIODeviceTransport(const TQIODeviceTransport&);
TQIODeviceTransport& operator=(const TQIODeviceTransport&);
- stdcxx::shared_ptr<QIODevice> dev_;
+ std::shared_ptr<QIODevice> dev_;
};
}
}
diff --git a/lib/cpp/src/thrift/qt/TQTcpServer.cpp b/lib/cpp/src/thrift/qt/TQTcpServer.cpp
index c4669d7..0404482 100644
--- a/lib/cpp/src/thrift/qt/TQTcpServer.cpp
+++ b/lib/cpp/src/thrift/qt/TQTcpServer.cpp
@@ -17,14 +17,15 @@
* under the License.
*/
+#include <functional>
+#include <memory>
+
#include <thrift/qt/TQTcpServer.h>
#include <thrift/qt/TQIODeviceTransport.h>
#include <QMetaType>
#include <QTcpSocket>
-#include <thrift/stdcxx.h>
-
#include <thrift/protocol/TProtocol.h>
#include <thrift/async/TAsyncProcessor.h>
@@ -33,10 +34,10 @@
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportException;
using apache::thrift::transport::TQIODeviceTransport;
-using apache::thrift::stdcxx::bind;
-using apache::thrift::stdcxx::function;
-using apache::thrift::stdcxx::placeholders::_1;
-using apache::thrift::stdcxx::shared_ptr;
+using std::bind;
+using std::function;
+using std::placeholders::_1;
+using std::shared_ptr;
QT_USE_NAMESPACE
@@ -66,8 +67,7 @@
connect(server.get(), SIGNAL(newConnection()), SLOT(processIncoming()));
}
-TQTcpServer::~TQTcpServer() {
-}
+TQTcpServer::~TQTcpServer() = default;
void TQTcpServer::processIncoming() {
while (server_->hasPendingConnections()) {
@@ -90,7 +90,7 @@
}
ctxMap_[connection.get()]
- = shared_ptr<ConnectionContext>(new ConnectionContext(connection, transport, iprot, oprot));
+ = std::make_shared<ConnectionContext>(connection, transport, iprot, oprot);
connect(connection.get(), SIGNAL(readyRead()), SLOT(beginDecode()));
@@ -99,7 +99,7 @@
}
void TQTcpServer::beginDecode() {
- QTcpSocket* connection(qobject_cast<QTcpSocket*>(sender()));
+ auto* connection(qobject_cast<QTcpSocket*>(sender()));
Q_ASSERT(connection);
if (ctxMap_.find(connection) == ctxMap_.end()) {
@@ -124,7 +124,7 @@
}
void TQTcpServer::socketClosed() {
- QTcpSocket* connection(qobject_cast<QTcpSocket*>(sender()));
+ auto* connection(qobject_cast<QTcpSocket*>(sender()));
Q_ASSERT(connection);
scheduleDeleteConnectionContext(connection);
}
diff --git a/lib/cpp/src/thrift/qt/TQTcpServer.h b/lib/cpp/src/thrift/qt/TQTcpServer.h
index 0d32afa..25994ab 100644
--- a/lib/cpp/src/thrift/qt/TQTcpServer.h
+++ b/lib/cpp/src/thrift/qt/TQTcpServer.h
@@ -23,7 +23,7 @@
#include <QObject>
#include <QTcpServer>
-#include <thrift/stdcxx.h>
+#include <memory>
namespace apache {
namespace thrift {
@@ -47,11 +47,11 @@
class TQTcpServer : public QObject {
Q_OBJECT
public:
- TQTcpServer(stdcxx::shared_ptr<QTcpServer> server,
- stdcxx::shared_ptr<TAsyncProcessor> processor,
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory> protocolFactory,
- QObject* parent = NULL);
- virtual ~TQTcpServer();
+ TQTcpServer(std::shared_ptr<QTcpServer> server,
+ std::shared_ptr<TAsyncProcessor> processor,
+ std::shared_ptr<apache::thrift::protocol::TProtocolFactory> protocolFactory,
+ QObject* parent = nullptr);
+ ~TQTcpServer() override;
private Q_SLOTS:
void processIncoming();
@@ -65,13 +65,13 @@
struct ConnectionContext;
void scheduleDeleteConnectionContext(QTcpSocket* connection);
- void finish(stdcxx::shared_ptr<ConnectionContext> ctx, bool healthy);
+ void finish(std::shared_ptr<ConnectionContext> ctx, bool healthy);
- stdcxx::shared_ptr<QTcpServer> server_;
- stdcxx::shared_ptr<TAsyncProcessor> processor_;
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
+ std::shared_ptr<QTcpServer> server_;
+ std::shared_ptr<TAsyncProcessor> processor_;
+ std::shared_ptr<apache::thrift::protocol::TProtocolFactory> pfact_;
- typedef std::map<QTcpSocket*, stdcxx::shared_ptr<ConnectionContext> > ConnectionContextMap;
+ typedef std::map<QTcpSocket*, std::shared_ptr<ConnectionContext> > ConnectionContextMap;
ConnectionContextMap ctxMap_;
};
}
diff --git a/lib/cpp/src/thrift/server/TConnectedClient.cpp b/lib/cpp/src/thrift/server/TConnectedClient.cpp
index 33ec3a9..9a78e3e 100644
--- a/lib/cpp/src/thrift/server/TConnectedClient.cpp
+++ b/lib/cpp/src/thrift/server/TConnectedClient.cpp
@@ -28,7 +28,7 @@
using apache::thrift::server::TServerEventHandler;
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportException;
-using stdcxx::shared_ptr;
+using std::shared_ptr;
using std::string;
TConnectedClient::TConnectedClient(const shared_ptr<TProcessor>& processor,
@@ -42,11 +42,10 @@
outputProtocol_(outputProtocol),
eventHandler_(eventHandler),
client_(client),
- opaqueContext_(0) {
+ opaqueContext_(nullptr) {
}
-TConnectedClient::~TConnectedClient() {
-}
+TConnectedClient::~TConnectedClient() = default;
void TConnectedClient::run() {
if (eventHandler_) {
diff --git a/lib/cpp/src/thrift/server/TConnectedClient.h b/lib/cpp/src/thrift/server/TConnectedClient.h
index 2f9d4c9..071571a 100644
--- a/lib/cpp/src/thrift/server/TConnectedClient.h
+++ b/lib/cpp/src/thrift/server/TConnectedClient.h
@@ -20,7 +20,7 @@
#ifndef _THRIFT_SERVER_TCONNECTEDCLIENT_H_
#define _THRIFT_SERVER_TCONNECTEDCLIENT_H_ 1
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/TProcessor.h>
#include <thrift/protocol/TProtocol.h>
#include <thrift/server/TServer.h>
@@ -49,16 +49,16 @@
* @param[in] client the TTransport representing the client
*/
TConnectedClient(
- const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocol>& inputProtocol,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocol>& outputProtocol,
- const stdcxx::shared_ptr<apache::thrift::server::TServerEventHandler>& eventHandler,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransport>& client);
+ const std::shared_ptr<apache::thrift::TProcessor>& processor,
+ const std::shared_ptr<apache::thrift::protocol::TProtocol>& inputProtocol,
+ const std::shared_ptr<apache::thrift::protocol::TProtocol>& outputProtocol,
+ const std::shared_ptr<apache::thrift::server::TServerEventHandler>& eventHandler,
+ const std::shared_ptr<apache::thrift::transport::TTransport>& client);
/**
* Destructor.
*/
- virtual ~TConnectedClient();
+ ~TConnectedClient() override;
/**
* Drive the client until it is done.
@@ -76,7 +76,7 @@
* handle unexpected exceptions by logging
* cleanup()
*/
- virtual void run() /* override */;
+ void run() override /* override */;
protected:
/**
@@ -92,11 +92,11 @@
virtual void cleanup();
private:
- stdcxx::shared_ptr<apache::thrift::TProcessor> processor_;
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> inputProtocol_;
- stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> outputProtocol_;
- stdcxx::shared_ptr<apache::thrift::server::TServerEventHandler> eventHandler_;
- stdcxx::shared_ptr<apache::thrift::transport::TTransport> client_;
+ std::shared_ptr<apache::thrift::TProcessor> processor_;
+ std::shared_ptr<apache::thrift::protocol::TProtocol> inputProtocol_;
+ std::shared_ptr<apache::thrift::protocol::TProtocol> outputProtocol_;
+ std::shared_ptr<apache::thrift::server::TServerEventHandler> eventHandler_;
+ std::shared_ptr<apache::thrift::transport::TTransport> client_;
/**
* Context acquired from the eventHandler_ if one exists.
diff --git a/lib/cpp/src/thrift/server/TNonblockingServer.cpp b/lib/cpp/src/thrift/server/TNonblockingServer.cpp
index 194d59f..eea0427 100644
--- a/lib/cpp/src/thrift/server/TNonblockingServer.cpp
+++ b/lib/cpp/src/thrift/server/TNonblockingServer.cpp
@@ -22,7 +22,7 @@
#include <thrift/server/TNonblockingServer.h>
#include <thrift/concurrency/Exception.h>
#include <thrift/transport/TSocket.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/transport/PlatformSocket.h>
#include <algorithm>
@@ -84,7 +84,7 @@
using namespace apache::thrift::concurrency;
using apache::thrift::transport::TSocket;
using apache::thrift::transport::TTransportException;
-using stdcxx::shared_ptr;
+using std::shared_ptr;
/// Three states for sockets: recv frame size, recv data, and send mode
enum TSocketState { SOCKET_RECV_FRAMING, SOCKET_RECV, SOCKET_SEND };
@@ -119,10 +119,10 @@
TNonblockingServer* server_;
/// TProcessor
- stdcxx::shared_ptr<TProcessor> processor_;
+ std::shared_ptr<TProcessor> processor_;
/// Object wrapping network socket
- stdcxx::shared_ptr<TSocket> tSocket_;
+ std::shared_ptr<TSocket> tSocket_;
/// Libevent object
struct event event_;
@@ -164,23 +164,23 @@
int32_t callsForResize_;
/// Transport to read from
- stdcxx::shared_ptr<TMemoryBuffer> inputTransport_;
+ std::shared_ptr<TMemoryBuffer> inputTransport_;
/// Transport that processor writes to
- stdcxx::shared_ptr<TMemoryBuffer> outputTransport_;
+ std::shared_ptr<TMemoryBuffer> outputTransport_;
/// extra transport generated by transport factory (e.g. BufferedRouterTransport)
- stdcxx::shared_ptr<TTransport> factoryInputTransport_;
- stdcxx::shared_ptr<TTransport> factoryOutputTransport_;
+ std::shared_ptr<TTransport> factoryInputTransport_;
+ std::shared_ptr<TTransport> factoryOutputTransport_;
/// Protocol decoder
- stdcxx::shared_ptr<TProtocol> inputProtocol_;
+ std::shared_ptr<TProtocol> inputProtocol_;
/// Protocol encoder
- stdcxx::shared_ptr<TProtocol> outputProtocol_;
+ std::shared_ptr<TProtocol> outputProtocol_;
/// Server event handler, if any
- stdcxx::shared_ptr<TServerEventHandler> serverEventHandler_;
+ std::shared_ptr<TServerEventHandler> serverEventHandler_;
/// Thrift call context, if any
void* connectionContext_;
@@ -213,9 +213,9 @@
class Task;
/// Constructor
- TConnection(stdcxx::shared_ptr<TSocket> socket,
+ TConnection(std::shared_ptr<TSocket> socket,
TNonblockingIOThread* ioThread) {
- readBuffer_ = NULL;
+ readBuffer_ = nullptr;
readBufferSize_ = 0;
ioThread_ = ioThread;
@@ -249,7 +249,7 @@
void init(TNonblockingIOThread* ioThread);
/// set socket for connection
- void setSocket(stdcxx::shared_ptr<TSocket> socket);
+ void setSocket(std::shared_ptr<TSocket> socket);
/**
* This is called when the application transitions from one state into
@@ -305,10 +305,10 @@
TAppState getState() const { return appState_; }
/// return the TSocket transport wrapping this network connection
- stdcxx::shared_ptr<TSocket> getTSocket() const { return tSocket_; }
+ std::shared_ptr<TSocket> getTSocket() const { return tSocket_; }
/// return the server event handler if any
- stdcxx::shared_ptr<TServerEventHandler> getServerEventHandler() { return serverEventHandler_; }
+ std::shared_ptr<TServerEventHandler> getServerEventHandler() { return serverEventHandler_; }
/// return the Thrift connection context if any
void* getConnectionContext() { return connectionContext_; }
@@ -316,9 +316,9 @@
class TNonblockingServer::TConnection::Task : public Runnable {
public:
- Task(stdcxx::shared_ptr<TProcessor> processor,
- stdcxx::shared_ptr<TProtocol> input,
- stdcxx::shared_ptr<TProtocol> output,
+ Task(std::shared_ptr<TProcessor> processor,
+ std::shared_ptr<TProtocol> input,
+ std::shared_ptr<TProtocol> output,
TConnection* connection)
: processor_(processor),
input_(input),
@@ -327,7 +327,7 @@
serverEventHandler_(connection_->getServerEventHandler()),
connectionContext_(connection_->getConnectionContext()) {}
- void run() {
+ void run() override {
try {
for (;;) {
if (serverEventHandler_) {
@@ -363,11 +363,11 @@
TConnection* getTConnection() { return connection_; }
private:
- stdcxx::shared_ptr<TProcessor> processor_;
- stdcxx::shared_ptr<TProtocol> input_;
- stdcxx::shared_ptr<TProtocol> output_;
+ std::shared_ptr<TProcessor> processor_;
+ std::shared_ptr<TProtocol> input_;
+ std::shared_ptr<TProtocol> output_;
TConnection* connection_;
- stdcxx::shared_ptr<TServerEventHandler> serverEventHandler_;
+ std::shared_ptr<TServerEventHandler> serverEventHandler_;
void* connectionContext_;
};
@@ -380,7 +380,7 @@
readBufferPos_ = 0;
readWant_ = 0;
- writeBuffer_ = NULL;
+ writeBuffer_ = nullptr;
writeBufferSize_ = 0;
writeBufferPos_ = 0;
largestWriteBufferSize_ = 0;
@@ -407,14 +407,14 @@
if (serverEventHandler_) {
connectionContext_ = serverEventHandler_->createContext(inputProtocol_, outputProtocol_);
} else {
- connectionContext_ = NULL;
+ connectionContext_ = nullptr;
}
// Get the processor
processor_ = server_->getProcessor(inputProtocol_, outputProtocol_, tSocket_);
}
-void TNonblockingServer::TConnection::setSocket(stdcxx::shared_ptr<TSocket> socket) {
+void TNonblockingServer::TConnection::setSocket(std::shared_ptr<TSocket> socket) {
tSocket_ = socket;
}
@@ -570,7 +570,7 @@
// Currently if there is no output protocol factory,
// we assume header transport (without having to create
// a new transport and check)
- return getOutputProtocolFactory() == NULL;
+ return getOutputProtocolFactory() == nullptr;
}
/**
@@ -610,7 +610,7 @@
// We are setting up a Task to do this work and we will wait on it
// Create task and dispatch to the thread manager
- stdcxx::shared_ptr<Runnable> task = stdcxx::shared_ptr<Runnable>(
+ std::shared_ptr<Runnable> task = std::shared_ptr<Runnable>(
new Task(processor_, inputProtocol_, outputProtocol_, this));
// The application is now waiting on the task to finish
appState_ = APP_WAIT_TASK;
@@ -687,7 +687,7 @@
socketState_ = SOCKET_SEND;
// Put the frame size into the write buffer
- int32_t frameSize = (int32_t)htonl(writeBufferSize_ - 4);
+ auto frameSize = (int32_t)htonl(writeBufferSize_ - 4);
memcpy(writeBuffer_, &frameSize, 4);
// Socket into write mode
@@ -720,7 +720,7 @@
case APP_INIT:
// Clear write buffer variables
- writeBuffer_ = NULL;
+ writeBuffer_ = nullptr;
writeBufferPos_ = 0;
writeBufferSize_ = 0;
@@ -749,8 +749,8 @@
newSize *= 2;
}
- uint8_t* newBuffer = (uint8_t*)std::realloc(readBuffer_, newSize);
- if (newBuffer == NULL) {
+ auto* newBuffer = (uint8_t*)std::realloc(readBuffer_, newSize);
+ if (newBuffer == nullptr) {
// nothing else to be done...
throw std::bad_alloc();
}
@@ -829,7 +829,7 @@
event_base_set(ioThread_->getEventBase(), &event_);
// Add the event
- if (event_add(&event_, 0) == -1) {
+ if (event_add(&event_, nullptr) == -1) {
GlobalOutput.perror("TConnection::setFlags(): could not event_add", THRIFT_GET_SOCKET_ERROR);
}
}
@@ -843,7 +843,7 @@
if (serverEventHandler_) {
serverEventHandler_->deleteContext(connectionContext_, inputProtocol_, outputProtocol_);
}
- ioThread_ = NULL;
+ ioThread_ = nullptr;
// Close the socket
tSocket_->close();
@@ -862,7 +862,7 @@
void TNonblockingServer::TConnection::checkIdleBufferMemLimit(size_t readLimit, size_t writeLimit) {
if (readLimit > 0 && readBufferSize_ > readLimit) {
free(readBuffer_);
- readBuffer_ = NULL;
+ readBuffer_ = nullptr;
readBufferSize_ = 0;
}
@@ -888,9 +888,9 @@
// objects and the Thread objects have shared_ptrs to the TNonblockingIOThread
// objects (as runnable) so these objects will never deallocate without help.
while (!ioThreads_.empty()) {
- stdcxx::shared_ptr<TNonblockingIOThread> iot = ioThreads_.back();
+ std::shared_ptr<TNonblockingIOThread> iot = ioThreads_.back();
ioThreads_.pop_back();
- iot->setThread(stdcxx::shared_ptr<Thread>());
+ iot->setThread(std::shared_ptr<Thread>());
}
}
@@ -898,7 +898,7 @@
* Creates a new connection either by reusing an object off the stack or
* by allocating a new one entirely
*/
-TNonblockingServer::TConnection* TNonblockingServer::createConnection(stdcxx::shared_ptr<TSocket> socket) {
+TNonblockingServer::TConnection* TNonblockingServer::createConnection(std::shared_ptr<TSocket> socket) {
// Check the stack
Guard g(connMutex_);
@@ -910,7 +910,7 @@
TNonblockingIOThread* ioThread = ioThreads_[selectedThreadIdx].get();
// Check the connection stack to see if we can re-use
- TConnection* result = NULL;
+ TConnection* result = nullptr;
if (connectionStack_.empty()) {
result = new TConnection(socket, ioThread);
++numTConnections_;
@@ -954,7 +954,7 @@
assert(fd == serverSocket_);
// Going to accept a new client socket
- stdcxx::shared_ptr<TSocket> clientSocket;
+ std::shared_ptr<TSocket> clientSocket;
clientSocket = serverTransport_->accept();
if (clientSocket) {
@@ -979,7 +979,7 @@
TConnection* clientConnection = createConnection(clientSocket);
// Fail fast if we could not create a TConnection object
- if (clientConnection == NULL) {
+ if (clientConnection == nullptr) {
GlobalOutput.printf("thriftServerEventHandler: failed TConnection factory");
clientSocket->close();
return;
@@ -1017,13 +1017,13 @@
}
-void TNonblockingServer::setThreadManager(stdcxx::shared_ptr<ThreadManager> threadManager) {
+void TNonblockingServer::setThreadManager(std::shared_ptr<ThreadManager> threadManager) {
threadManager_ = threadManager;
if (threadManager) {
threadManager->setExpireCallback(
- apache::thrift::stdcxx::bind(&TNonblockingServer::expireClose,
+ std::bind(&TNonblockingServer::expireClose,
this,
- apache::thrift::stdcxx::placeholders::_1));
+ std::placeholders::_1));
threadPoolProcessing_ = true;
} else {
threadPoolProcessing_ = false;
@@ -1055,7 +1055,7 @@
bool TNonblockingServer::drainPendingTask() {
if (threadManager_) {
- stdcxx::shared_ptr<Runnable> task = threadManager_->removeNextPending();
+ std::shared_ptr<Runnable> task = threadManager_->removeNextPending();
if (task) {
TConnection* connection = static_cast<TConnection::Task*>(task.get())->getTConnection();
assert(connection && connection->getServer() && connection->getState() == APP_WAIT_TASK);
@@ -1066,7 +1066,7 @@
return false;
}
-void TNonblockingServer::expireClose(stdcxx::shared_ptr<Runnable> task) {
+void TNonblockingServer::expireClose(std::shared_ptr<Runnable> task) {
TConnection* connection = static_cast<TConnection::Task*>(task.get())->getTConnection();
assert(connection && connection->getServer() && connection->getState() == APP_WAIT_TASK);
connection->forceClose();
@@ -1074,8 +1074,8 @@
void TNonblockingServer::stop() {
// Breaks the event loop in all threads so that they end ASAP.
- for (uint32_t i = 0; i < ioThreads_.size(); ++i) {
- ioThreads_[i]->stop();
+ for (auto & ioThread : ioThreads_) {
+ ioThread->stop();
}
}
@@ -1118,12 +1118,7 @@
// Launch all the secondary IO threads in separate threads
if (ioThreads_.size() > 1) {
- ioThreadFactory_.reset(new PlatformThreadFactory(
-#if !USE_BOOST_THREAD && !USE_STD_THREAD
- PlatformThreadFactory::OTHER, // scheduler
- PlatformThreadFactory::NORMAL, // priority
- 1, // stack size (MB)
-#endif
+ ioThreadFactory_.reset(new ThreadFactory(
false // detached
));
@@ -1148,7 +1143,7 @@
void TNonblockingServer::serve() {
if (ioThreads_.empty())
- registerEvents(NULL);
+ registerEvents(nullptr);
// Run the primary (listener) IO thread loop in our main thread; this will
// only return when the server is shutting down.
@@ -1167,10 +1162,13 @@
bool useHighPriority)
: server_(server),
number_(number),
+ threadId_{},
listenSocket_(listenSocket),
useHighPriority_(useHighPriority),
- eventBase_(NULL),
- ownEventBase_(false) {
+ eventBase_(nullptr),
+ ownEventBase_(false),
+ serverEvent_{},
+ notificationEvent_{} {
notificationPipeFDs_[0] = -1;
notificationPipeFDs_[1] = -1;
}
@@ -1191,13 +1189,13 @@
listenSocket_ = THRIFT_INVALID_SOCKET;
}
- for (int i = 0; i < 2; ++i) {
- if (notificationPipeFDs_[i] >= 0) {
- if (0 != ::THRIFT_CLOSESOCKET(notificationPipeFDs_[i])) {
+ for (auto notificationPipeFD : notificationPipeFDs_) {
+ if (notificationPipeFD >= 0) {
+ if (0 != ::THRIFT_CLOSESOCKET(notificationPipeFD)) {
GlobalOutput.perror("TNonblockingIOThread notificationPipe close(): ",
THRIFT_GET_SOCKET_ERROR);
}
- notificationPipeFDs_[i] = THRIFT_INVALID_SOCKET;
+ notificationPipeFD = THRIFT_INVALID_SOCKET;
}
}
}
@@ -1213,13 +1211,13 @@
::THRIFT_CLOSESOCKET(notificationPipeFDs_[1]);
throw TException("TNonblockingServer::createNotificationPipe() THRIFT_O_NONBLOCK");
}
- for (int i = 0; i < 2; ++i) {
+ for (auto notificationPipeFD : notificationPipeFDs_) {
#if LIBEVENT_VERSION_NUMBER < 0x02000000
int flags;
- if ((flags = THRIFT_FCNTL(notificationPipeFDs_[i], F_GETFD, 0)) < 0
- || THRIFT_FCNTL(notificationPipeFDs_[i], F_SETFD, flags | FD_CLOEXEC) < 0) {
+ if ((flags = THRIFT_FCNTL(notificationPipeFD, F_GETFD, 0)) < 0
+ || THRIFT_FCNTL(notificationPipeFD, F_SETFD, flags | FD_CLOEXEC) < 0) {
#else
- if (evutil_make_socket_closeonexec(notificationPipeFDs_[i]) < 0) {
+ if (evutil_make_socket_closeonexec(notificationPipeFD) < 0) {
#endif
::THRIFT_CLOSESOCKET(notificationPipeFDs_[0]);
::THRIFT_CLOSESOCKET(notificationPipeFDs_[1]);
@@ -1236,9 +1234,9 @@
void TNonblockingIOThread::registerEvents() {
threadId_ = Thread::get_current();
- assert(eventBase_ == 0);
+ assert(eventBase_ == nullptr);
eventBase_ = getServer()->getUserEventBase();
- if (eventBase_ == NULL) {
+ if (eventBase_ == nullptr) {
eventBase_ = event_base_new();
ownEventBase_ = true;
}
@@ -1260,7 +1258,7 @@
event_base_set(eventBase_, &serverEvent_);
// Add the event and start up the server
- if (-1 == event_add(&serverEvent_, 0)) {
+ if (-1 == event_add(&serverEvent_, nullptr)) {
throw TException(
"TNonblockingServer::serve(): "
"event_add() failed on server listen event");
@@ -1281,7 +1279,7 @@
event_base_set(eventBase_, ¬ificationEvent_);
// Add the event and start up the server
- if (-1 == event_add(¬ificationEvent_, 0)) {
+ if (-1 == event_add(¬ificationEvent_, nullptr)) {
throw TException(
"TNonblockingServer::serve(): "
"event_add() failed on task-done notification event");
@@ -1290,7 +1288,7 @@
}
bool TNonblockingIOThread::notify(TNonblockingServer::TConnection* conn) {
- THRIFT_SOCKET fd = getNotificationSendFD();
+ auto fd = getNotificationSendFD();
if (fd < 0) {
return false;
}
@@ -1373,16 +1371,16 @@
/* static */
void TNonblockingIOThread::notifyHandler(evutil_socket_t fd, short which, void* v) {
- TNonblockingIOThread* ioThread = (TNonblockingIOThread*)v;
+ auto* ioThread = (TNonblockingIOThread*)v;
assert(ioThread);
(void)which;
while (true) {
- TNonblockingServer::TConnection* connection = 0;
+ TNonblockingServer::TConnection* connection = nullptr;
const int kSize = sizeof(connection);
long nBytes = recv(fd, cast_sockopt(&connection), kSize, 0);
if (nBytes == kSize) {
- if (connection == NULL) {
+ if (connection == nullptr) {
// this is the command to stop our thread, exit the handler!
ioThread->breakLoop(false);
return;
@@ -1425,7 +1423,7 @@
// same thread, this means the thread can't be blocking in the event
// loop either.
if (!Thread::is_current(threadId_)) {
- notify(NULL);
+ notify(nullptr);
} else {
// cause the loop to stop ASAP - even if it has things to do in it
event_base_loopbreak(eventBase_);
@@ -1462,14 +1460,14 @@
}
void TNonblockingIOThread::run() {
- if (eventBase_ == NULL) {
+ if (eventBase_ == nullptr) {
registerEvents();
}
if (useHighPriority_) {
setCurrentThreadHighPriority(true);
}
- if (eventBase_ != NULL)
+ if (eventBase_ != nullptr)
{
GlobalOutput.printf("TNonblockingServer: IO thread #%d entering loop...", number_);
// Run libevent engine, never returns, invokes calls to eventHandler
diff --git a/lib/cpp/src/thrift/server/TNonblockingServer.h b/lib/cpp/src/thrift/server/TNonblockingServer.h
index f95a729..82bc375 100644
--- a/lib/cpp/src/thrift/server/TNonblockingServer.h
+++ b/lib/cpp/src/thrift/server/TNonblockingServer.h
@@ -21,7 +21,7 @@
#define _THRIFT_SERVER_TNONBLOCKINGSERVER_H_ 1
#include <thrift/Thrift.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/server/TServer.h>
#include <thrift/transport/PlatformSocket.h>
#include <thrift/transport/TBufferTransports.h>
@@ -30,7 +30,7 @@
#include <thrift/concurrency/ThreadManager.h>
#include <climits>
#include <thrift/concurrency/Thread.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/concurrency/Mutex.h>
#include <stack>
#include <vector>
@@ -53,7 +53,7 @@
using apache::thrift::protocol::TProtocol;
using apache::thrift::concurrency::Runnable;
using apache::thrift::concurrency::ThreadManager;
-using apache::thrift::concurrency::PlatformThreadFactory;
+using apache::thrift::concurrency::ThreadFactory;
using apache::thrift::concurrency::ThreadFactory;
using apache::thrift::concurrency::Thread;
using apache::thrift::concurrency::Mutex;
@@ -160,16 +160,16 @@
event_base* userEventBase_;
/// For processing via thread pool, may be NULL
- stdcxx::shared_ptr<ThreadManager> threadManager_;
+ std::shared_ptr<ThreadManager> threadManager_;
/// Is thread pool processing?
bool threadPoolProcessing_;
// Factory to create the IO threads
- stdcxx::shared_ptr<PlatformThreadFactory> ioThreadFactory_;
+ std::shared_ptr<ThreadFactory> ioThreadFactory_;
// Vector of IOThread objects that will handle our IO
- std::vector<stdcxx::shared_ptr<TNonblockingIOThread> > ioThreads_;
+ std::vector<std::shared_ptr<TNonblockingIOThread> > ioThreads_;
// Index of next IO Thread to be used (for round-robin)
uint32_t nextIOThread_;
@@ -264,7 +264,7 @@
/*
*/
- stdcxx::shared_ptr<TNonblockingServerTransport> serverTransport_;
+ std::shared_ptr<TNonblockingServerTransport> serverTransport_;
/**
* Called when server socket had something happen. We accept all waiting
@@ -280,7 +280,7 @@
numIOThreads_ = DEFAULT_IO_THREADS;
nextIOThread_ = 0;
useHighPriorityIOThreads_ = false;
- userEventBase_ = NULL;
+ userEventBase_ = nullptr;
threadPoolProcessing_ = false;
numTConnections_ = 0;
numActiveProcessors_ = 0;
@@ -301,24 +301,24 @@
}
public:
- TNonblockingServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport)
+ TNonblockingServer(const std::shared_ptr<TProcessorFactory>& processorFactory,
+ const std::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport)
: TServer(processorFactory), serverTransport_(serverTransport) {
init();
}
- TNonblockingServer(const stdcxx::shared_ptr<TProcessor>& processor,
- const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport)
+ TNonblockingServer(const std::shared_ptr<TProcessor>& processor,
+ const std::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport)
: TServer(processor), serverTransport_(serverTransport) {
init();
}
- TNonblockingServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
- const stdcxx::shared_ptr<ThreadManager>& threadManager
- = stdcxx::shared_ptr<ThreadManager>())
+ TNonblockingServer(const std::shared_ptr<TProcessorFactory>& processorFactory,
+ const std::shared_ptr<TProtocolFactory>& protocolFactory,
+ const std::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
+ const std::shared_ptr<ThreadManager>& threadManager
+ = std::shared_ptr<ThreadManager>())
: TServer(processorFactory), serverTransport_(serverTransport) {
init();
@@ -327,11 +327,11 @@
setThreadManager(threadManager);
}
- TNonblockingServer(const stdcxx::shared_ptr<TProcessor>& processor,
- const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
- const stdcxx::shared_ptr<ThreadManager>& threadManager
- = stdcxx::shared_ptr<ThreadManager>())
+ TNonblockingServer(const std::shared_ptr<TProcessor>& processor,
+ const std::shared_ptr<TProtocolFactory>& protocolFactory,
+ const std::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
+ const std::shared_ptr<ThreadManager>& threadManager
+ = std::shared_ptr<ThreadManager>())
: TServer(processor), serverTransport_(serverTransport) {
init();
@@ -340,14 +340,14 @@
setThreadManager(threadManager);
}
- TNonblockingServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& outputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
- const stdcxx::shared_ptr<ThreadManager>& threadManager
- = stdcxx::shared_ptr<ThreadManager>())
+ TNonblockingServer(const std::shared_ptr<TProcessorFactory>& processorFactory,
+ const std::shared_ptr<TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<TProtocolFactory>& outputProtocolFactory,
+ const std::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
+ const std::shared_ptr<ThreadManager>& threadManager
+ = std::shared_ptr<ThreadManager>())
: TServer(processorFactory), serverTransport_(serverTransport) {
init();
@@ -358,14 +358,14 @@
setThreadManager(threadManager);
}
- TNonblockingServer(const stdcxx::shared_ptr<TProcessor>& processor,
- const stdcxx::shared_ptr<TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& outputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
- const stdcxx::shared_ptr<ThreadManager>& threadManager
- = stdcxx::shared_ptr<ThreadManager>())
+ TNonblockingServer(const std::shared_ptr<TProcessor>& processor,
+ const std::shared_ptr<TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<TProtocolFactory>& outputProtocolFactory,
+ const std::shared_ptr<apache::thrift::transport::TNonblockingServerTransport>& serverTransport,
+ const std::shared_ptr<ThreadManager>& threadManager
+ = std::shared_ptr<ThreadManager>())
: TServer(processor), serverTransport_(serverTransport) {
init();
@@ -376,19 +376,17 @@
setThreadManager(threadManager);
}
- ~TNonblockingServer();
+ ~TNonblockingServer() override;
- void setThreadManager(stdcxx::shared_ptr<ThreadManager> threadManager);
+ void setThreadManager(std::shared_ptr<ThreadManager> threadManager);
int getListenPort() { return serverTransport_->getListenPort(); }
- stdcxx::shared_ptr<ThreadManager> getThreadManager() { return threadManager_; }
+ std::shared_ptr<ThreadManager> getThreadManager() { return threadManager_; }
/**
* Sets the number of IO threads used by this server. Can only be used before
- * the call to serve() and has no effect afterwards. We always use a
- * PosixThreadFactory for the IO worker threads, because they must joinable
- * for clean shutdown.
+ * the call to serve() and has no effect afterwards.
*/
void setNumIOThreads(size_t numThreads) {
numIOThreads_ = numThreads;
@@ -421,7 +419,7 @@
bool isThreadPoolProcessing() const { return threadPoolProcessing_; }
- void addTask(stdcxx::shared_ptr<Runnable> task) {
+ void addTask(std::shared_ptr<Runnable> task) {
threadManager_->add(task, 0LL, taskExpireTime_);
}
@@ -671,12 +669,12 @@
* Main workhorse function, starts up the server listening on a port and
* loops over the libevent handler.
*/
- void serve();
+ void serve() override;
/**
* Causes the server to terminate gracefully (can be called from any thread).
*/
- void stop();
+ void stop() override;
/// Creates a socket to listen on and binds it to the local port.
void createAndListenOnSocket();
@@ -709,7 +707,7 @@
*
* @param task the runnable associated with the expired task.
*/
- void expireClose(stdcxx::shared_ptr<Runnable> task);
+ void expireClose(std::shared_ptr<Runnable> task);
/**
* Return an initialized connection object. Creates or recovers from
@@ -721,7 +719,7 @@
* @param addrLen the length of addr
* @return pointer to initialized TConnection object.
*/
- TConnection* createConnection(stdcxx::shared_ptr<TSocket> socket);
+ TConnection* createConnection(std::shared_ptr<TSocket> socket);
/**
* Returns a connection to pool or deletion. If the connection pool
@@ -743,7 +741,7 @@
THRIFT_SOCKET listenSocket,
bool useHighPriority);
- ~TNonblockingIOThread();
+ ~TNonblockingIOThread() override;
// Returns the event-base for this thread.
event_base* getEventBase() const { return eventBase_; }
@@ -765,16 +763,16 @@
evutil_socket_t getNotificationRecvFD() const { return notificationPipeFDs_[0]; }
// Returns the actual thread object associated with this IO thread.
- stdcxx::shared_ptr<Thread> getThread() const { return thread_; }
+ std::shared_ptr<Thread> getThread() const { return thread_; }
// Sets the actual thread object associated with this IO thread.
- void setThread(const stdcxx::shared_ptr<Thread>& t) { thread_ = t; }
+ void setThread(const std::shared_ptr<Thread>& t) { thread_ = t; }
// Used by TConnection objects to indicate processing has finished.
bool notify(TNonblockingServer::TConnection* conn);
// Enters the event loop and does not return until a call to stop().
- virtual void run();
+ void run() override;
// Exits the event loop as soon as possible.
void stop();
@@ -853,7 +851,7 @@
evutil_socket_t notificationPipeFDs_[2];
/// Actual IO Thread
- stdcxx::shared_ptr<Thread> thread_;
+ std::shared_ptr<Thread> thread_;
};
}
}
diff --git a/lib/cpp/src/thrift/server/TServer.h b/lib/cpp/src/thrift/server/TServer.h
index f4cd7bc..d2eabde 100644
--- a/lib/cpp/src/thrift/server/TServer.h
+++ b/lib/cpp/src/thrift/server/TServer.h
@@ -25,7 +25,7 @@
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/concurrency/Thread.h>
-#include <thrift/stdcxx.h>
+#include <memory>
namespace apache {
namespace thrift {
@@ -48,7 +48,7 @@
*/
class TServerEventHandler {
public:
- virtual ~TServerEventHandler() {}
+ virtual ~TServerEventHandler() = default;
/**
* Called before the server begins.
@@ -58,11 +58,11 @@
/**
* Called when a new client has connected and is about to being processing.
*/
- virtual void* createContext(stdcxx::shared_ptr<TProtocol> input,
- stdcxx::shared_ptr<TProtocol> output) {
+ virtual void* createContext(std::shared_ptr<TProtocol> input,
+ std::shared_ptr<TProtocol> output) {
(void)input;
(void)output;
- return NULL;
+ return nullptr;
}
/**
@@ -70,8 +70,8 @@
* context.
*/
virtual void deleteContext(void* serverContext,
- stdcxx::shared_ptr<TProtocol> input,
- stdcxx::shared_ptr<TProtocol> output) {
+ std::shared_ptr<TProtocol> input,
+ std::shared_ptr<TProtocol> output) {
(void)serverContext;
(void)input;
(void)output;
@@ -80,7 +80,7 @@
/**
* Called when a client is about to call the processor.
*/
- virtual void processContext(void* serverContext, stdcxx::shared_ptr<TTransport> transport) {
+ virtual void processContext(void* serverContext, std::shared_ptr<TTransport> transport) {
(void)serverContext;
(void)transport;
}
@@ -89,7 +89,7 @@
/**
* Prevent direct instantiation.
*/
- TServerEventHandler() {}
+ TServerEventHandler() = default;
};
/**
@@ -98,71 +98,71 @@
*/
class TServer : public concurrency::Runnable {
public:
- virtual ~TServer() {}
+ ~TServer() override = default;
virtual void serve() = 0;
virtual void stop() {}
// Allows running the server as a Runnable thread
- virtual void run() { serve(); }
+ void run() override { serve(); }
- stdcxx::shared_ptr<TProcessorFactory> getProcessorFactory() { return processorFactory_; }
+ std::shared_ptr<TProcessorFactory> getProcessorFactory() { return processorFactory_; }
- stdcxx::shared_ptr<TServerTransport> getServerTransport() { return serverTransport_; }
+ std::shared_ptr<TServerTransport> getServerTransport() { return serverTransport_; }
- stdcxx::shared_ptr<TTransportFactory> getInputTransportFactory() { return inputTransportFactory_; }
+ std::shared_ptr<TTransportFactory> getInputTransportFactory() { return inputTransportFactory_; }
- stdcxx::shared_ptr<TTransportFactory> getOutputTransportFactory() {
+ std::shared_ptr<TTransportFactory> getOutputTransportFactory() {
return outputTransportFactory_;
}
- stdcxx::shared_ptr<TProtocolFactory> getInputProtocolFactory() { return inputProtocolFactory_; }
+ std::shared_ptr<TProtocolFactory> getInputProtocolFactory() { return inputProtocolFactory_; }
- stdcxx::shared_ptr<TProtocolFactory> getOutputProtocolFactory() { return outputProtocolFactory_; }
+ std::shared_ptr<TProtocolFactory> getOutputProtocolFactory() { return outputProtocolFactory_; }
- stdcxx::shared_ptr<TServerEventHandler> getEventHandler() { return eventHandler_; }
+ std::shared_ptr<TServerEventHandler> getEventHandler() { return eventHandler_; }
protected:
- TServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory)
+ TServer(const std::shared_ptr<TProcessorFactory>& processorFactory)
: processorFactory_(processorFactory) {
- setInputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
- setOutputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
- setInputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
- setOutputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
+ setInputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
+ setOutputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
+ setInputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
+ setOutputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
}
- TServer(const stdcxx::shared_ptr<TProcessor>& processor)
+ TServer(const std::shared_ptr<TProcessor>& processor)
: processorFactory_(new TSingletonProcessorFactory(processor)) {
- setInputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
- setOutputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
- setInputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
- setOutputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
+ setInputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
+ setOutputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
+ setInputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
+ setOutputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
}
- TServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<TServerTransport>& serverTransport)
+ TServer(const std::shared_ptr<TProcessorFactory>& processorFactory,
+ const std::shared_ptr<TServerTransport>& serverTransport)
: processorFactory_(processorFactory), serverTransport_(serverTransport) {
- setInputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
- setOutputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
- setInputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
- setOutputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
+ setInputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
+ setOutputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
+ setInputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
+ setOutputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
}
- TServer(const stdcxx::shared_ptr<TProcessor>& processor,
- const stdcxx::shared_ptr<TServerTransport>& serverTransport)
+ TServer(const std::shared_ptr<TProcessor>& processor,
+ const std::shared_ptr<TServerTransport>& serverTransport)
: processorFactory_(new TSingletonProcessorFactory(processor)),
serverTransport_(serverTransport) {
- setInputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
- setOutputTransportFactory(stdcxx::shared_ptr<TTransportFactory>(new TTransportFactory()));
- setInputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
- setOutputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
+ setInputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
+ setOutputTransportFactory(std::shared_ptr<TTransportFactory>(new TTransportFactory()));
+ setInputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
+ setOutputProtocolFactory(std::shared_ptr<TProtocolFactory>(new TBinaryProtocolFactory()));
}
- TServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory)
+ TServer(const std::shared_ptr<TProcessorFactory>& processorFactory,
+ const std::shared_ptr<TServerTransport>& serverTransport,
+ const std::shared_ptr<TTransportFactory>& transportFactory,
+ const std::shared_ptr<TProtocolFactory>& protocolFactory)
: processorFactory_(processorFactory),
serverTransport_(serverTransport),
inputTransportFactory_(transportFactory),
@@ -170,10 +170,10 @@
inputProtocolFactory_(protocolFactory),
outputProtocolFactory_(protocolFactory) {}
- TServer(const stdcxx::shared_ptr<TProcessor>& processor,
- const stdcxx::shared_ptr<TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory)
+ TServer(const std::shared_ptr<TProcessor>& processor,
+ const std::shared_ptr<TServerTransport>& serverTransport,
+ const std::shared_ptr<TTransportFactory>& transportFactory,
+ const std::shared_ptr<TProtocolFactory>& protocolFactory)
: processorFactory_(new TSingletonProcessorFactory(processor)),
serverTransport_(serverTransport),
inputTransportFactory_(transportFactory),
@@ -181,12 +181,12 @@
inputProtocolFactory_(protocolFactory),
outputProtocolFactory_(protocolFactory) {}
- TServer(const stdcxx::shared_ptr<TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& outputProtocolFactory)
+ TServer(const std::shared_ptr<TProcessorFactory>& processorFactory,
+ const std::shared_ptr<TServerTransport>& serverTransport,
+ const std::shared_ptr<TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<TProtocolFactory>& outputProtocolFactory)
: processorFactory_(processorFactory),
serverTransport_(serverTransport),
inputTransportFactory_(inputTransportFactory),
@@ -194,12 +194,12 @@
inputProtocolFactory_(inputProtocolFactory),
outputProtocolFactory_(outputProtocolFactory) {}
- TServer(const stdcxx::shared_ptr<TProcessor>& processor,
- const stdcxx::shared_ptr<TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& outputProtocolFactory)
+ TServer(const std::shared_ptr<TProcessor>& processor,
+ const std::shared_ptr<TServerTransport>& serverTransport,
+ const std::shared_ptr<TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<TProtocolFactory>& outputProtocolFactory)
: processorFactory_(new TSingletonProcessorFactory(processor)),
serverTransport_(serverTransport),
inputTransportFactory_(inputTransportFactory),
@@ -214,9 +214,9 @@
* call). This allows the TProcessorFactory to return a different processor
* for each connection if it desires.
*/
- stdcxx::shared_ptr<TProcessor> getProcessor(stdcxx::shared_ptr<TProtocol> inputProtocol,
- stdcxx::shared_ptr<TProtocol> outputProtocol,
- stdcxx::shared_ptr<TTransport> transport) {
+ std::shared_ptr<TProcessor> getProcessor(std::shared_ptr<TProtocol> inputProtocol,
+ std::shared_ptr<TProtocol> outputProtocol,
+ std::shared_ptr<TTransport> transport) {
TConnectionInfo connInfo;
connInfo.input = inputProtocol;
connInfo.output = outputProtocol;
@@ -225,35 +225,35 @@
}
// Class variables
- stdcxx::shared_ptr<TProcessorFactory> processorFactory_;
- stdcxx::shared_ptr<TServerTransport> serverTransport_;
+ std::shared_ptr<TProcessorFactory> processorFactory_;
+ std::shared_ptr<TServerTransport> serverTransport_;
- stdcxx::shared_ptr<TTransportFactory> inputTransportFactory_;
- stdcxx::shared_ptr<TTransportFactory> outputTransportFactory_;
+ std::shared_ptr<TTransportFactory> inputTransportFactory_;
+ std::shared_ptr<TTransportFactory> outputTransportFactory_;
- stdcxx::shared_ptr<TProtocolFactory> inputProtocolFactory_;
- stdcxx::shared_ptr<TProtocolFactory> outputProtocolFactory_;
+ std::shared_ptr<TProtocolFactory> inputProtocolFactory_;
+ std::shared_ptr<TProtocolFactory> outputProtocolFactory_;
- stdcxx::shared_ptr<TServerEventHandler> eventHandler_;
+ std::shared_ptr<TServerEventHandler> eventHandler_;
public:
- void setInputTransportFactory(stdcxx::shared_ptr<TTransportFactory> inputTransportFactory) {
+ void setInputTransportFactory(std::shared_ptr<TTransportFactory> inputTransportFactory) {
inputTransportFactory_ = inputTransportFactory;
}
- void setOutputTransportFactory(stdcxx::shared_ptr<TTransportFactory> outputTransportFactory) {
+ void setOutputTransportFactory(std::shared_ptr<TTransportFactory> outputTransportFactory) {
outputTransportFactory_ = outputTransportFactory;
}
- void setInputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory> inputProtocolFactory) {
+ void setInputProtocolFactory(std::shared_ptr<TProtocolFactory> inputProtocolFactory) {
inputProtocolFactory_ = inputProtocolFactory;
}
- void setOutputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory> outputProtocolFactory) {
+ void setOutputProtocolFactory(std::shared_ptr<TProtocolFactory> outputProtocolFactory) {
outputProtocolFactory_ = outputProtocolFactory;
}
- void setServerEventHandler(stdcxx::shared_ptr<TServerEventHandler> eventHandler) {
+ void setServerEventHandler(std::shared_ptr<TServerEventHandler> eventHandler) {
eventHandler_ = eventHandler;
}
};
diff --git a/lib/cpp/src/thrift/server/TServerFramework.cpp b/lib/cpp/src/thrift/server/TServerFramework.cpp
index ae38336..35f3b25 100644
--- a/lib/cpp/src/thrift/server/TServerFramework.cpp
+++ b/lib/cpp/src/thrift/server/TServerFramework.cpp
@@ -29,8 +29,8 @@
using apache::thrift::concurrency::Synchronized;
using apache::thrift::protocol::TProtocol;
using apache::thrift::protocol::TProtocolFactory;
-using apache::thrift::stdcxx::bind;
-using apache::thrift::stdcxx::shared_ptr;
+using std::bind;
+using std::shared_ptr;
using apache::thrift::transport::TServerTransport;
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportException;
@@ -91,8 +91,7 @@
limit_(INT64_MAX) {
}
-TServerFramework::~TServerFramework() {
-}
+TServerFramework::~TServerFramework() = default;
template <typename T>
static void releaseOneDescriptor(const string& name, T& pTransport) {
@@ -161,7 +160,7 @@
outputProtocol,
eventHandler_,
client),
- bind(&TServerFramework::disposeConnectedClient, this, stdcxx::placeholders::_1)));
+ bind(&TServerFramework::disposeConnectedClient, this, std::placeholders::_1)));
} catch (TTransportException& ttx) {
releaseOneDescriptor("inputTransport", inputTransport);
diff --git a/lib/cpp/src/thrift/server/TServerFramework.h b/lib/cpp/src/thrift/server/TServerFramework.h
index 706fd49..dac79ef 100644
--- a/lib/cpp/src/thrift/server/TServerFramework.h
+++ b/lib/cpp/src/thrift/server/TServerFramework.h
@@ -20,7 +20,7 @@
#ifndef _THRIFT_SERVER_TSERVERFRAMEWORK_H_
#define _THRIFT_SERVER_TSERVERFRAMEWORK_H_ 1
-#include <thrift/stdcxx.h>
+#include <memory>
#include <stdint.h>
#include <thrift/TProcessor.h>
#include <thrift/concurrency/Monitor.h>
@@ -48,34 +48,34 @@
class TServerFramework : public TServer {
public:
TServerFramework(
- const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
+ const std::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
TServerFramework(
- const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
+ const std::shared_ptr<apache::thrift::TProcessor>& processor,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
TServerFramework(
- const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
+ const std::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
TServerFramework(
- const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
+ const std::shared_ptr<apache::thrift::TProcessor>& processor,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
- virtual ~TServerFramework();
+ ~TServerFramework() override;
/**
* Accept clients from the TServerTransport and add them for processing.
@@ -84,12 +84,12 @@
* Post-conditions (return guarantees):
* The serverTransport will be closed.
*/
- virtual void serve();
+ void serve() override;
/**
* Interrupt serve() so that it meets post-conditions and returns.
*/
- virtual void stop();
+ void stop() override;
/**
* Get the concurrent client limit.
@@ -130,7 +130,7 @@
*
* \param[in] pClient the newly connected client
*/
- virtual void onClientConnected(const stdcxx::shared_ptr<TConnectedClient>& pClient) = 0;
+ virtual void onClientConnected(const std::shared_ptr<TConnectedClient>& pClient) = 0;
/**
* A client has disconnected.
@@ -149,7 +149,7 @@
* client rate limiting after onClientConnected returns by blocking the
* serve() thread if the limit has been reached.
*/
- void newlyConnectedClient(const stdcxx::shared_ptr<TConnectedClient>& pClient);
+ void newlyConnectedClient(const std::shared_ptr<TConnectedClient>& pClient);
/**
* Smart pointer client deletion.
diff --git a/lib/cpp/src/thrift/server/TSimpleServer.cpp b/lib/cpp/src/thrift/server/TSimpleServer.cpp
index a0afbbe..ba7a183 100644
--- a/lib/cpp/src/thrift/server/TSimpleServer.cpp
+++ b/lib/cpp/src/thrift/server/TSimpleServer.cpp
@@ -29,7 +29,7 @@
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportException;
using apache::thrift::transport::TTransportFactory;
-using stdcxx::shared_ptr;
+using std::shared_ptr;
using std::string;
TSimpleServer::TSimpleServer(const shared_ptr<TProcessorFactory>& processorFactory,
@@ -78,8 +78,7 @@
TServerFramework::setConcurrentClientLimit(1);
}
-TSimpleServer::~TSimpleServer() {
-}
+TSimpleServer::~TSimpleServer() = default;
/**
* The main body of customized implementation for TSimpleServer is quite simple:
diff --git a/lib/cpp/src/thrift/server/TSimpleServer.h b/lib/cpp/src/thrift/server/TSimpleServer.h
index ac4ed34..3afeb79 100644
--- a/lib/cpp/src/thrift/server/TSimpleServer.h
+++ b/lib/cpp/src/thrift/server/TSimpleServer.h
@@ -34,41 +34,41 @@
class TSimpleServer : public TServerFramework {
public:
TSimpleServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
+ const std::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
TSimpleServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
+ const std::shared_ptr<apache::thrift::TProcessor>& processor,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory);
TSimpleServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
+ const std::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
TSimpleServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
+ const std::shared_ptr<apache::thrift::TProcessor>& processor,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory);
- virtual ~TSimpleServer();
+ ~TSimpleServer() override;
protected:
- virtual void onClientConnected(const stdcxx::shared_ptr<TConnectedClient>& pClient) /* override */;
- virtual void onClientDisconnected(TConnectedClient* pClient) /* override */;
+ void onClientConnected(const std::shared_ptr<TConnectedClient>& pClient) override /* override */;
+ void onClientDisconnected(TConnectedClient* pClient) override /* override */;
private:
- void setConcurrentClientLimit(int64_t newLimit); // hide
+ void setConcurrentClientLimit(int64_t newLimit) override; // hide
};
}
}
diff --git a/lib/cpp/src/thrift/server/TThreadPoolServer.cpp b/lib/cpp/src/thrift/server/TThreadPoolServer.cpp
index f07ff84..121dde3 100644
--- a/lib/cpp/src/thrift/server/TThreadPoolServer.cpp
+++ b/lib/cpp/src/thrift/server/TThreadPoolServer.cpp
@@ -30,7 +30,7 @@
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportException;
using apache::thrift::transport::TTransportFactory;
-using stdcxx::shared_ptr;
+using std::shared_ptr;
using std::string;
TThreadPoolServer::TThreadPoolServer(const shared_ptr<TProcessorFactory>& processorFactory,
@@ -91,8 +91,7 @@
taskExpiration_(0) {
}
-TThreadPoolServer::~TThreadPoolServer() {
-}
+TThreadPoolServer::~TThreadPoolServer() = default;
void TThreadPoolServer::serve() {
TServerFramework::serve();
@@ -115,7 +114,7 @@
taskExpiration_ = value;
}
-stdcxx::shared_ptr<apache::thrift::concurrency::ThreadManager>
+std::shared_ptr<apache::thrift::concurrency::ThreadManager>
TThreadPoolServer::getThreadManager() const {
return threadManager_;
}
diff --git a/lib/cpp/src/thrift/server/TThreadPoolServer.h b/lib/cpp/src/thrift/server/TThreadPoolServer.h
index 94088d5..a9411b8 100644
--- a/lib/cpp/src/thrift/server/TThreadPoolServer.h
+++ b/lib/cpp/src/thrift/server/TThreadPoolServer.h
@@ -20,7 +20,7 @@
#ifndef _THRIFT_SERVER_TTHREADPOOLSERVER_H_
#define _THRIFT_SERVER_TTHREADPOOLSERVER_H_ 1
-#include <boost/atomic.hpp>
+#include <atomic>
#include <thrift/concurrency/ThreadManager.h>
#include <thrift/server/TServerFramework.h>
@@ -34,48 +34,48 @@
class TThreadPoolServer : public TServerFramework {
public:
TThreadPoolServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
- const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
+ const std::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
+ const std::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
= apache::thrift::concurrency::ThreadManager::newSimpleThreadManager());
TThreadPoolServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
- const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
+ const std::shared_ptr<apache::thrift::TProcessor>& processor,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
+ const std::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
= apache::thrift::concurrency::ThreadManager::newSimpleThreadManager());
TThreadPoolServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
+ const std::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
+ const std::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
= apache::thrift::concurrency::ThreadManager::newSimpleThreadManager());
TThreadPoolServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
+ const std::shared_ptr<apache::thrift::TProcessor>& processor,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
+ const std::shared_ptr<apache::thrift::concurrency::ThreadManager>& threadManager
= apache::thrift::concurrency::ThreadManager::newSimpleThreadManager());
- virtual ~TThreadPoolServer();
+ ~TThreadPoolServer() override;
/**
* Post-conditions (return guarantees):
* There will be no clients connected.
*/
- virtual void serve();
+ void serve() override;
virtual int64_t getTimeout() const;
virtual void setTimeout(int64_t value);
@@ -83,15 +83,15 @@
virtual int64_t getTaskExpiration() const;
virtual void setTaskExpiration(int64_t value);
- virtual stdcxx::shared_ptr<apache::thrift::concurrency::ThreadManager> getThreadManager() const;
+ virtual std::shared_ptr<apache::thrift::concurrency::ThreadManager> getThreadManager() const;
protected:
- virtual void onClientConnected(const stdcxx::shared_ptr<TConnectedClient>& pClient) /* override */;
- virtual void onClientDisconnected(TConnectedClient* pClient) /* override */;
+ void onClientConnected(const std::shared_ptr<TConnectedClient>& pClient) override /* override */;
+ void onClientDisconnected(TConnectedClient* pClient) override /* override */;
- stdcxx::shared_ptr<apache::thrift::concurrency::ThreadManager> threadManager_;
- boost::atomic<int64_t> timeout_;
- boost::atomic<int64_t> taskExpiration_;
+ std::shared_ptr<apache::thrift::concurrency::ThreadManager> threadManager_;
+ std::atomic<int64_t> timeout_;
+ std::atomic<int64_t> taskExpiration_;
};
}
diff --git a/lib/cpp/src/thrift/server/TThreadedServer.cpp b/lib/cpp/src/thrift/server/TThreadedServer.cpp
index 3fe5aa6..79dcc70 100644
--- a/lib/cpp/src/thrift/server/TThreadedServer.cpp
+++ b/lib/cpp/src/thrift/server/TThreadedServer.cpp
@@ -18,8 +18,8 @@
*/
#include <string>
-#include <thrift/stdcxx.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <memory>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/server/TThreadedServer.h>
namespace apache {
@@ -32,8 +32,8 @@
using apache::thrift::concurrency::ThreadFactory;
using apache::thrift::protocol::TProtocol;
using apache::thrift::protocol::TProtocolFactory;
-using apache::thrift::stdcxx::make_shared;
-using apache::thrift::stdcxx::shared_ptr;
+using std::make_shared;
+using std::shared_ptr;
using apache::thrift::transport::TServerTransport;
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportException;
@@ -89,8 +89,7 @@
threadFactory_(threadFactory) {
}
-TThreadedServer::~TThreadedServer() {
-}
+TThreadedServer::~TThreadedServer() = default;
void TThreadedServer::serve() {
TServerFramework::serve();
@@ -107,7 +106,7 @@
void TThreadedServer::drainDeadClients() {
// we're in a monitor here
while (!deadClientMap_.empty()) {
- ClientMap::iterator it = deadClientMap_.begin();
+ auto it = deadClientMap_.begin();
it->second->join();
deadClientMap_.erase(it);
}
@@ -125,9 +124,9 @@
void TThreadedServer::onClientDisconnected(TConnectedClient* pClient) {
Synchronized sync(clientMonitor_);
drainDeadClients(); // use the outgoing thread to do some maintenance on our dead client backlog
- ClientMap::iterator it = activeClientMap_.find(pClient);
+ auto it = activeClientMap_.find(pClient);
if (it != activeClientMap_.end()) {
- ClientMap::iterator end = it;
+ auto end = it;
deadClientMap_.insert(it, ++end);
activeClientMap_.erase(it);
}
@@ -140,8 +139,7 @@
: pClient_(pClient) {
}
-TThreadedServer::TConnectedClientRunner::~TConnectedClientRunner() {
-}
+TThreadedServer::TConnectedClientRunner::~TConnectedClientRunner() = default;
void TThreadedServer::TConnectedClientRunner::run() /* override */ {
pClient_->run(); // Run the client
diff --git a/lib/cpp/src/thrift/server/TThreadedServer.h b/lib/cpp/src/thrift/server/TThreadedServer.h
index 1e0a824..756e5a0 100644
--- a/lib/cpp/src/thrift/server/TThreadedServer.h
+++ b/lib/cpp/src/thrift/server/TThreadedServer.h
@@ -22,7 +22,7 @@
#include <map>
#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/concurrency/Thread.h>
#include <thrift/server/TServerFramework.h>
@@ -38,52 +38,52 @@
class TThreadedServer : public TServerFramework {
public:
TThreadedServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
- const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
- = stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
- new apache::thrift::concurrency::PlatformThreadFactory(false)));
+ const std::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
+ const std::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
+ = std::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
+ new apache::thrift::concurrency::ThreadFactory(false)));
TThreadedServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
- const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
- = stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
- new apache::thrift::concurrency::PlatformThreadFactory(false)));
+ const std::shared_ptr<apache::thrift::TProcessor>& processor,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& transportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& protocolFactory,
+ const std::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
+ = std::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
+ new apache::thrift::concurrency::ThreadFactory(false)));
TThreadedServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
- = stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
- new apache::thrift::concurrency::PlatformThreadFactory(false)));
+ const std::shared_ptr<apache::thrift::TProcessorFactory>& processorFactory,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
+ const std::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
+ = std::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
+ new apache::thrift::concurrency::ThreadFactory(false)));
TThreadedServer(
- const stdcxx::shared_ptr<apache::thrift::TProcessor>& processor,
- const stdcxx::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
- const stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
- = stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
- new apache::thrift::concurrency::PlatformThreadFactory(false)));
+ const std::shared_ptr<apache::thrift::TProcessor>& processor,
+ const std::shared_ptr<apache::thrift::transport::TServerTransport>& serverTransport,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& inputTransportFactory,
+ const std::shared_ptr<apache::thrift::transport::TTransportFactory>& outputTransportFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& inputProtocolFactory,
+ const std::shared_ptr<apache::thrift::protocol::TProtocolFactory>& outputProtocolFactory,
+ const std::shared_ptr<apache::thrift::concurrency::ThreadFactory>& threadFactory
+ = std::shared_ptr<apache::thrift::concurrency::ThreadFactory>(
+ new apache::thrift::concurrency::ThreadFactory(false)));
- virtual ~TThreadedServer();
+ ~TThreadedServer() override;
/**
* Post-conditions (return guarantees):
* There will be no clients connected.
*/
- virtual void serve();
+ void serve() override;
protected:
/**
@@ -95,14 +95,14 @@
/**
* Implementation of TServerFramework::onClientConnected
*/
- virtual void onClientConnected(const stdcxx::shared_ptr<TConnectedClient>& pClient) /* override */;
+ void onClientConnected(const std::shared_ptr<TConnectedClient>& pClient) override /* override */;
/**
* Implementation of TServerFramework::onClientDisconnected
*/
- virtual void onClientDisconnected(TConnectedClient *pClient) /* override */;
+ void onClientDisconnected(TConnectedClient *pClient) override /* override */;
- stdcxx::shared_ptr<apache::thrift::concurrency::ThreadFactory> threadFactory_;
+ std::shared_ptr<apache::thrift::concurrency::ThreadFactory> threadFactory_;
/**
* A helper wrapper used to wrap the client in something we can use to maintain
@@ -114,16 +114,16 @@
class TConnectedClientRunner : public apache::thrift::concurrency::Runnable
{
public:
- TConnectedClientRunner(const stdcxx::shared_ptr<TConnectedClient>& pClient);
- virtual ~TConnectedClientRunner();
- void run() /* override */;
+ TConnectedClientRunner(const std::shared_ptr<TConnectedClient>& pClient);
+ ~TConnectedClientRunner() override;
+ void run() override /* override */;
private:
- stdcxx::shared_ptr<TConnectedClient> pClient_;
+ std::shared_ptr<TConnectedClient> pClient_;
};
apache::thrift::concurrency::Monitor clientMonitor_;
- typedef std::map<TConnectedClient *, stdcxx::shared_ptr<apache::thrift::concurrency::Thread> > ClientMap;
+ typedef std::map<TConnectedClient *, std::shared_ptr<apache::thrift::concurrency::Thread> > ClientMap;
/**
* A map of active clients
diff --git a/lib/cpp/src/thrift/stdcxx.h b/lib/cpp/src/thrift/stdcxx.h
deleted file mode 100644
index c8cabf5..0000000
--- a/lib/cpp/src/thrift/stdcxx.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef _THRIFT_STDCXX_H_
-#define _THRIFT_STDCXX_H_ 1
-
-#include <boost/config.hpp>
-#include <boost/version.hpp>
-
-///////////////////////////////////////////////////////////////////
-//
-// functional (function, bind)
-//
-///////////////////////////////////////////////////////////////////
-
-#if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) || (defined(_MSC_VER) && _MSC_VER < 1800) || defined(FORCE_BOOST_FUNCTIONAL)
-#if (BOOST_VERSION <= 106500)
-#include <boost/tr1/functional.hpp>
-#else
-#include <tr1/functional>
-#endif
-#define _THRIFT_FUNCTIONAL_TR1_ 1
-#endif
-
-#if _THRIFT_FUNCTIONAL_TR1_
-
- namespace apache { namespace thrift { namespace stdcxx {
-
- using ::std::tr1::bind;
- using ::std::tr1::function;
-
- namespace placeholders {
- using ::std::tr1::placeholders::_1;
- using ::std::tr1::placeholders::_2;
- using ::std::tr1::placeholders::_3;
- using ::std::tr1::placeholders::_4;
- using ::std::tr1::placeholders::_5;
- using ::std::tr1::placeholders::_6;
- using ::std::tr1::placeholders::_7;
- using ::std::tr1::placeholders::_8;
- using ::std::tr1::placeholders::_9;
- } // apache::thrift::stdcxx::placeholders
- }}} // apache::thrift::stdcxx
-
-#else
-
- #include <functional>
-
- namespace apache { namespace thrift { namespace stdcxx {
- using ::std::bind;
- using ::std::function;
-
- namespace placeholders {
- using ::std::placeholders::_1;
- using ::std::placeholders::_2;
- using ::std::placeholders::_3;
- using ::std::placeholders::_4;
- using ::std::placeholders::_5;
- using ::std::placeholders::_6;
- using ::std::placeholders::_7;
- using ::std::placeholders::_8;
- using ::std::placeholders::_9;
- } // apache::thrift::stdcxx::placeholders
- }}} // apache::thrift::stdcxx
-
-#endif
-
-///////////////////////////////////////////////////////////////////
-//
-// Smart Pointers
-//
-///////////////////////////////////////////////////////////////////
-
-// We can use std for memory functions only if the compiler supports template aliasing
-// The macro BOOST_NO_CXX11_SMART_PTR is defined as 1 under Visual Studio 2010 and 2012
-// which do not support the feature, so we must continue to use C++98 and boost on them.
-// We cannot use __cplusplus to detect this either, since Microsoft advertises an older one.
-
-#if defined(BOOST_NO_CXX11_SMART_PTR) || (defined(_MSC_VER) && _MSC_VER < 1800) || defined(FORCE_BOOST_SMART_PTR)
-#include <boost/smart_ptr.hpp>
-#else
-#include <memory>
-#endif
-
-namespace apache { namespace thrift { namespace stdcxx {
-
-#if defined(BOOST_NO_CXX11_SMART_PTR) || (defined(_MSC_VER) && _MSC_VER < 1800) || defined(FORCE_BOOST_SMART_PTR)
-
- using ::boost::const_pointer_cast;
- using ::boost::dynamic_pointer_cast;
- using ::boost::enable_shared_from_this;
- using ::boost::make_shared;
- using ::boost::scoped_ptr;
- using ::boost::shared_ptr;
- using ::boost::static_pointer_cast;
- using ::boost::weak_ptr;
-
-#else
-
- using ::std::const_pointer_cast;
- using ::std::dynamic_pointer_cast;
- using ::std::enable_shared_from_this;
- using ::std::make_shared;
- template <typename T> using scoped_ptr = std::unique_ptr<T>; // compiler must support template aliasing
- using ::std::shared_ptr;
- using ::std::static_pointer_cast;
- using ::std::weak_ptr;
-
-#endif
-
-}}} // apache::thrift::stdcxx
-
-#endif // #ifndef _THRIFT_STDCXX_H_
diff --git a/lib/cpp/src/thrift/thrift_export.h b/lib/cpp/src/thrift/thrift_export.h
new file mode 100644
index 0000000..f5c059f
--- /dev/null
+++ b/lib/cpp/src/thrift/thrift_export.h
@@ -0,0 +1,20 @@
+#ifndef THRIFT_EXPORT_H
+#define THRIFT_EXPORT_H
+
+#ifdef THRIFT_STATIC_DEFINE
+# define THRIFT_EXPORT
+#elif defined(_MSC_VER )
+# ifndef THRIFT_EXPORT
+# ifdef thrift_EXPORTS
+ /* We are building this library */
+# define THRIFT_EXPORT __declspec(dllexport)
+# else
+ /* We are using this library */
+# define THRIFT_EXPORT __declspec(dllimport)
+# endif
+# endif
+#else
+# define THRIFT_EXPORT
+#endif
+
+#endif /* THRIFT_EXPORT_H */
diff --git a/lib/cpp/src/thrift/transport/TBufferTransports.cpp b/lib/cpp/src/thrift/transport/TBufferTransports.cpp
index 9ac2f84..4bb8713 100644
--- a/lib/cpp/src/thrift/transport/TBufferTransports.cpp
+++ b/lib/cpp/src/thrift/transport/TBufferTransports.cpp
@@ -29,7 +29,7 @@
namespace transport {
uint32_t TBufferedTransport::readSlow(uint8_t* buf, uint32_t len) {
- uint32_t have = static_cast<uint32_t>(rBound_ - rBase_);
+ auto have = static_cast<uint32_t>(rBound_ - rBase_);
// We should only take the slow path if we can't satisfy the read
// with the data already in the buffer.
@@ -61,8 +61,8 @@
}
void TBufferedTransport::writeSlow(const uint8_t* buf, uint32_t len) {
- uint32_t have_bytes = static_cast<uint32_t>(wBase_ - wBuf_.get());
- uint32_t space = static_cast<uint32_t>(wBound_ - wBase_);
+ auto have_bytes = static_cast<uint32_t>(wBase_ - wBuf_.get());
+ auto space = static_cast<uint32_t>(wBound_ - wBase_);
// We should only take the slow path if we can't accommodate the write
// with the free space already in the buffer.
assert(wBound_ - wBase_ < static_cast<ptrdiff_t>(len));
@@ -114,12 +114,12 @@
(void)len;
// Simply return NULL. We don't know if there is actually data available on
// the underlying transport, so calling read() might block.
- return NULL;
+ return nullptr;
}
void TBufferedTransport::flush() {
// Write out any data waiting in the write buffer.
- uint32_t have_bytes = static_cast<uint32_t>(wBase_ - wBuf_.get());
+ auto have_bytes = static_cast<uint32_t>(wBase_ - wBuf_.get());
if (have_bytes > 0) {
// Note that we reset wBase_ prior to the underlying write
// to ensure we're in a sane state (i.e. internal buffer cleaned)
@@ -134,7 +134,7 @@
uint32_t TFramedTransport::readSlow(uint8_t* buf, uint32_t len) {
uint32_t want = len;
- uint32_t have = static_cast<uint32_t>(rBound_ - rBase_);
+ auto have = static_cast<uint32_t>(rBound_ - rBase_);
// We should only take the slow path if we can't satisfy the read
// with the data already in the buffer.
@@ -217,7 +217,7 @@
void TFramedTransport::writeSlow(const uint8_t* buf, uint32_t len) {
// Double buffer size until sufficient.
- uint32_t have = static_cast<uint32_t>(wBase_ - wBuf_.get());
+ auto have = static_cast<uint32_t>(wBase_ - wBuf_.get());
uint32_t new_size = wBufSize_;
if (len + have < have /* overflow */ || len + have > 0x7fffffff) {
throw TTransportException(TTransportException::BAD_ARGS,
@@ -231,7 +231,7 @@
// so we can use realloc here.
// Allocate new buffer.
- uint8_t* new_buf = new uint8_t[new_size];
+ auto* new_buf = new uint8_t[new_size];
// Copy the old buffer to the new one.
memcpy(new_buf, wBuf_.get(), have);
@@ -292,12 +292,12 @@
// Don't try to be clever with shifting buffers.
// If the fast path failed let the protocol use its slow path.
// Besides, who is going to try to borrow across messages?
- return NULL;
+ return nullptr;
}
uint32_t TFramedTransport::readEnd() {
// include framing bytes
- uint32_t bytes_read = static_cast<uint32_t>(rBound_ - rBuf_.get() + sizeof(uint32_t));
+ auto bytes_read = static_cast<uint32_t>(rBound_ - rBuf_.get() + sizeof(uint32_t));
if (rBufSize_ > bufReclaimThresh_) {
rBufSize_ = 0;
@@ -335,7 +335,7 @@
uint32_t TMemoryBuffer::readAppendToString(std::string& str, uint32_t len) {
// Don't get some stupid assertion failure.
- if (buffer_ == NULL) {
+ if (buffer_ == nullptr) {
return 0;
}
@@ -372,8 +372,8 @@
}
// Allocate into a new pointer so we don't bork ours if it fails.
- uint8_t* new_buffer = static_cast<uint8_t*>(std::realloc(buffer_, new_size));
- if (new_buffer == NULL) {
+ auto* new_buffer = static_cast<uint8_t*>(std::realloc(buffer_, new_size));
+ if (new_buffer == nullptr) {
throw std::bad_alloc();
}
@@ -408,7 +408,7 @@
*len = available_read();
return rBase_;
}
- return NULL;
+ return nullptr;
}
}
}
diff --git a/lib/cpp/src/thrift/transport/TBufferTransports.h b/lib/cpp/src/thrift/transport/TBufferTransports.h
index 79aace6..df06586 100644
--- a/lib/cpp/src/thrift/transport/TBufferTransports.h
+++ b/lib/cpp/src/thrift/transport/TBufferTransports.h
@@ -148,7 +148,7 @@
* performance-sensitive operation, so it is okay to just leave it to
* the concrete class to set up pointers correctly.
*/
- TBufferBase() : rBase_(NULL), rBound_(NULL), wBase_(NULL), wBound_(NULL) {}
+ TBufferBase() : rBase_(nullptr), rBound_(nullptr), wBase_(nullptr), wBound_(nullptr) {}
/// Convenience mutator for setting the read buffer.
void setReadBuffer(uint8_t* buf, uint32_t len) {
@@ -162,7 +162,7 @@
wBound_ = buf + len;
}
- virtual ~TBufferBase() {}
+ ~TBufferBase() override = default;
/// Reads begin here.
uint8_t* rBase_;
@@ -186,7 +186,7 @@
static const int DEFAULT_BUFFER_SIZE = 512;
/// Use default buffer sizes.
- TBufferedTransport(stdcxx::shared_ptr<TTransport> transport)
+ TBufferedTransport(std::shared_ptr<TTransport> transport)
: transport_(transport),
rBufSize_(DEFAULT_BUFFER_SIZE),
wBufSize_(DEFAULT_BUFFER_SIZE),
@@ -196,7 +196,7 @@
}
/// Use specified buffer sizes.
- TBufferedTransport(stdcxx::shared_ptr<TTransport> transport, uint32_t sz)
+ TBufferedTransport(std::shared_ptr<TTransport> transport, uint32_t sz)
: transport_(transport),
rBufSize_(sz),
wBufSize_(sz),
@@ -206,7 +206,7 @@
}
/// Use specified read and write buffer sizes.
- TBufferedTransport(stdcxx::shared_ptr<TTransport> transport, uint32_t rsz, uint32_t wsz)
+ TBufferedTransport(std::shared_ptr<TTransport> transport, uint32_t rsz, uint32_t wsz)
: transport_(transport),
rBufSize_(rsz),
wBufSize_(wsz),
@@ -215,32 +215,32 @@
initPointers();
}
- void open() { transport_->open(); }
+ void open() override { transport_->open(); }
- bool isOpen() { return transport_->isOpen(); }
+ bool isOpen() const override { return transport_->isOpen(); }
- bool peek() {
+ bool peek() override {
if (rBase_ == rBound_) {
setReadBuffer(rBuf_.get(), transport_->read(rBuf_.get(), rBufSize_));
}
return (rBound_ > rBase_);
}
- void close() {
+ void close() override {
flush();
transport_->close();
}
- virtual uint32_t readSlow(uint8_t* buf, uint32_t len);
+ uint32_t readSlow(uint8_t* buf, uint32_t len) override;
- virtual void writeSlow(const uint8_t* buf, uint32_t len);
+ void writeSlow(const uint8_t* buf, uint32_t len) override;
- void flush();
+ void flush() override;
/**
* Returns the origin of the underlying transport
*/
- virtual const std::string getOrigin() { return transport_->getOrigin(); }
+ const std::string getOrigin() const override { return transport_->getOrigin(); }
/**
* The following behavior is currently implemented by TBufferedTransport,
@@ -253,9 +253,9 @@
* will ever have to be copied again. For optimial performance,
* stay under this limit.
*/
- virtual const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len);
+ const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len) override;
- stdcxx::shared_ptr<TTransport> getUnderlyingTransport() { return transport_; }
+ std::shared_ptr<TTransport> getUnderlyingTransport() { return transport_; }
/*
* TVirtualTransport provides a default implementation of readAll().
@@ -270,7 +270,7 @@
// Write size never changes.
}
- stdcxx::shared_ptr<TTransport> transport_;
+ std::shared_ptr<TTransport> transport_;
uint32_t rBufSize_;
uint32_t wBufSize_;
@@ -284,15 +284,15 @@
*/
class TBufferedTransportFactory : public TTransportFactory {
public:
- TBufferedTransportFactory() {}
+ TBufferedTransportFactory() = default;
- virtual ~TBufferedTransportFactory() {}
+ ~TBufferedTransportFactory() override = default;
/**
* Wraps the transport into a buffered one.
*/
- virtual stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> trans) {
- return stdcxx::shared_ptr<TTransport>(new TBufferedTransport(trans));
+ std::shared_ptr<TTransport> getTransport(std::shared_ptr<TTransport> trans) override {
+ return std::shared_ptr<TTransport>(new TBufferedTransport(trans));
}
};
@@ -319,7 +319,7 @@
initPointers();
}
- TFramedTransport(stdcxx::shared_ptr<TTransport> transport)
+ TFramedTransport(std::shared_ptr<TTransport> transport)
: transport_(transport),
rBufSize_(0),
wBufSize_(DEFAULT_BUFFER_SIZE),
@@ -330,7 +330,7 @@
initPointers();
}
- TFramedTransport(stdcxx::shared_ptr<TTransport> transport,
+ TFramedTransport(std::shared_ptr<TTransport> transport,
uint32_t sz,
uint32_t bufReclaimThresh = (std::numeric_limits<uint32_t>::max)())
: transport_(transport),
@@ -343,30 +343,30 @@
initPointers();
}
- void open() { transport_->open(); }
+ void open() override { transport_->open(); }
- bool isOpen() { return transport_->isOpen(); }
+ bool isOpen() const override { return transport_->isOpen(); }
- bool peek() { return (rBase_ < rBound_) || transport_->peek(); }
+ bool peek() override { return (rBase_ < rBound_) || transport_->peek(); }
- void close() {
+ void close() override {
flush();
transport_->close();
}
- virtual uint32_t readSlow(uint8_t* buf, uint32_t len);
+ uint32_t readSlow(uint8_t* buf, uint32_t len) override;
- virtual void writeSlow(const uint8_t* buf, uint32_t len);
+ void writeSlow(const uint8_t* buf, uint32_t len) override;
- virtual void flush();
+ void flush() override;
- uint32_t readEnd();
+ uint32_t readEnd() override;
- uint32_t writeEnd();
+ uint32_t writeEnd() override;
- const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len);
+ const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len) override;
- stdcxx::shared_ptr<TTransport> getUnderlyingTransport() { return transport_; }
+ std::shared_ptr<TTransport> getUnderlyingTransport() { return transport_; }
/*
* TVirtualTransport provides a default implementation of readAll().
@@ -377,7 +377,7 @@
/**
* Returns the origin of the underlying transport
*/
- virtual const std::string getOrigin() { return transport_->getOrigin(); }
+ const std::string getOrigin() const override { return transport_->getOrigin(); }
/**
* Set the maximum size of the frame at read
@@ -399,7 +399,7 @@
virtual bool readFrame();
void initPointers() {
- setReadBuffer(NULL, 0);
+ setReadBuffer(nullptr, 0);
setWriteBuffer(wBuf_.get(), wBufSize_);
// Pad the buffer so we can insert the size later.
@@ -407,7 +407,7 @@
this->write((uint8_t*)&pad, sizeof(pad));
}
- stdcxx::shared_ptr<TTransport> transport_;
+ std::shared_ptr<TTransport> transport_;
uint32_t rBufSize_;
uint32_t wBufSize_;
@@ -423,15 +423,15 @@
*/
class TFramedTransportFactory : public TTransportFactory {
public:
- TFramedTransportFactory() {}
+ TFramedTransportFactory() = default;
- virtual ~TFramedTransportFactory() {}
+ ~TFramedTransportFactory() override = default;
/**
* Wraps the transport into a framed one.
*/
- virtual stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> trans) {
- return stdcxx::shared_ptr<TTransport>(new TFramedTransport(trans));
+ std::shared_ptr<TTransport> getTransport(std::shared_ptr<TTransport> trans) override {
+ return std::shared_ptr<TTransport>(new TFramedTransport(trans));
}
};
@@ -451,10 +451,10 @@
maxBufferSize_ = (std::numeric_limits<uint32_t>::max)();
- if (buf == NULL && size != 0) {
+ if (buf == nullptr && size != 0) {
assert(owner);
buf = (uint8_t*)std::malloc(size);
- if (buf == NULL) {
+ if (buf == nullptr) {
throw std::bad_alloc();
}
}
@@ -503,7 +503,7 @@
* Construct a TMemoryBuffer with a default-sized buffer,
* owned by the TMemoryBuffer object.
*/
- TMemoryBuffer() { initCommon(NULL, defaultSize, true, 0); }
+ TMemoryBuffer() { initCommon(nullptr, defaultSize, true, 0); }
/**
* Construct a TMemoryBuffer with a buffer of a specified size,
@@ -511,7 +511,7 @@
*
* @param sz The initial size of the buffer.
*/
- TMemoryBuffer(uint32_t sz) { initCommon(NULL, sz, true, 0); }
+ TMemoryBuffer(uint32_t sz) { initCommon(nullptr, sz, true, 0); }
/**
* Construct a TMemoryBuffer with buf as its initial contents.
@@ -524,7 +524,7 @@
* @param policy See @link MemoryPolicy @endlink .
*/
TMemoryBuffer(uint8_t* buf, uint32_t sz, MemoryPolicy policy = OBSERVE) {
- if (buf == NULL && sz != 0) {
+ if (buf == nullptr && sz != 0) {
throw TTransportException(TTransportException::BAD_ARGS,
"TMemoryBuffer given null buffer with non-zero size.");
}
@@ -535,7 +535,7 @@
initCommon(buf, sz, policy == TAKE_OWNERSHIP, sz);
break;
case COPY:
- initCommon(NULL, sz, true, 0);
+ initCommon(nullptr, sz, true, 0);
this->write(buf, sz);
break;
default:
@@ -544,19 +544,19 @@
}
}
- ~TMemoryBuffer() {
+ ~TMemoryBuffer() override {
if (owner_) {
std::free(buffer_);
}
}
- bool isOpen() { return true; }
+ bool isOpen() const override { return true; }
- bool peek() { return (rBase_ < wBase_); }
+ bool peek() override { return (rBase_ < wBase_); }
- void open() {}
+ void open() override {}
- void close() {}
+ void close() override {}
// TODO(dreiss): Make bufPtr const.
void getBuffer(uint8_t** bufPtr, uint32_t* sz) {
@@ -565,7 +565,7 @@
}
std::string getBufferAsString() {
- if (buffer_ == NULL) {
+ if (buffer_ == nullptr) {
return "";
}
uint8_t* buf;
@@ -575,7 +575,7 @@
}
void appendBufferToString(std::string& str) {
- if (buffer_ == NULL) {
+ if (buffer_ == nullptr) {
return;
}
uint8_t* buf;
@@ -634,9 +634,9 @@
uint32_t readAppendToString(std::string& str, uint32_t len);
// return number of bytes read
- uint32_t readEnd() {
+ uint32_t readEnd() override {
// This cast should be safe, because buffer_'s size is a uint32_t
- uint32_t bytes = static_cast<uint32_t>(rBase_ - buffer_);
+ auto bytes = static_cast<uint32_t>(rBase_ - buffer_);
if (rBase_ == wBase_) {
resetBuffer();
}
@@ -644,7 +644,7 @@
}
// Return number of bytes written
- uint32_t writeEnd() {
+ uint32_t writeEnd() override {
// This cast should be safe, because buffer_'s size is a uint32_t
return static_cast<uint32_t>(wBase_ - buffer_);
}
@@ -719,11 +719,11 @@
// Compute the position and available data for reading.
void computeRead(uint32_t len, uint8_t** out_start, uint32_t* out_give);
- uint32_t readSlow(uint8_t* buf, uint32_t len);
+ uint32_t readSlow(uint8_t* buf, uint32_t len) override;
- void writeSlow(const uint8_t* buf, uint32_t len);
+ void writeSlow(const uint8_t* buf, uint32_t len) override;
- const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len);
+ const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len) override;
// Data buffer
uint8_t* buffer_;
diff --git a/lib/cpp/src/thrift/transport/TFDTransport.h b/lib/cpp/src/thrift/transport/TFDTransport.h
index 5593d43..a3cf519 100644
--- a/lib/cpp/src/thrift/transport/TFDTransport.h
+++ b/lib/cpp/src/thrift/transport/TFDTransport.h
@@ -43,7 +43,7 @@
TFDTransport(int fd, ClosePolicy close_policy = NO_CLOSE_ON_DESTROY)
: fd_(fd), close_policy_(close_policy) {}
- ~TFDTransport() {
+ ~TFDTransport() override {
if (close_policy_ == CLOSE_ON_DESTROY) {
try {
close();
@@ -53,11 +53,11 @@
}
}
- bool isOpen() { return fd_ >= 0; }
+ bool isOpen() const override { return fd_ >= 0; }
- void open() {}
+ void open() override {}
- void close();
+ void close() override;
uint32_t read(uint8_t* buf, uint32_t len);
diff --git a/lib/cpp/src/thrift/transport/TFileTransport.cpp b/lib/cpp/src/thrift/transport/TFileTransport.cpp
index b08a5f1..53e5136 100644
--- a/lib/cpp/src/thrift/transport/TFileTransport.cpp
+++ b/lib/cpp/src/thrift/transport/TFileTransport.cpp
@@ -25,13 +25,6 @@
#include <thrift/concurrency/FunctionRunner.h>
#include <boost/version.hpp>
-#if (BOOST_VERSION >= 105700)
-#include <boost/move/unique_ptr.hpp>
-using boost::movelib::unique_ptr;
-#else
-#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
-using boost::interprocess::unique_ptr;
-#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
@@ -49,6 +42,7 @@
#include <cstring>
#include <iostream>
#include <limits>
+#include <memory>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
@@ -61,7 +55,7 @@
namespace thrift {
namespace transport {
-using stdcxx::shared_ptr;
+using std::shared_ptr;
using std::cerr;
using std::cout;
using std::endl;
@@ -71,8 +65,8 @@
TFileTransport::TFileTransport(string path, bool readOnly)
: readState_(),
- readBuff_(NULL),
- currentEvent_(NULL),
+ readBuff_(nullptr),
+ currentEvent_(nullptr),
readBuffSize_(DEFAULT_READ_BUFF_SIZE),
readTimeout_(NO_TAIL_READ_TIMEOUT),
chunkSize_(DEFAULT_CHUNK_SIZE),
@@ -84,8 +78,8 @@
eofSleepTime_(DEFAULT_EOF_SLEEP_TIME_US),
corruptedEventSleepTime_(DEFAULT_CORRUPTED_SLEEP_TIME_US),
writerThreadIOErrorSleepTime_(DEFAULT_WRITER_THREAD_SLEEP_TIME_US),
- dequeueBuffer_(NULL),
- enqueueBuffer_(NULL),
+ dequeueBuffer_(nullptr),
+ enqueueBuffer_(nullptr),
notFull_(&mutex_),
notEmpty_(&mutex_),
closing_(false),
@@ -147,22 +141,22 @@
if (dequeueBuffer_) {
delete dequeueBuffer_;
- dequeueBuffer_ = NULL;
+ dequeueBuffer_ = nullptr;
}
if (enqueueBuffer_) {
delete enqueueBuffer_;
- enqueueBuffer_ = NULL;
+ enqueueBuffer_ = nullptr;
}
if (readBuff_) {
delete[] readBuff_;
- readBuff_ = NULL;
+ readBuff_ = nullptr;
}
if (currentEvent_) {
delete currentEvent_;
- currentEvent_ = NULL;
+ currentEvent_ = nullptr;
}
// close logfile
@@ -203,8 +197,6 @@
enqueueEvent(buf, len);
}
-// this is needed until boost 1.57 as the older unique_ptr implementation
-// has no default deleter in interprocess
template <class _T>
struct uniqueDeleter
{
@@ -228,7 +220,7 @@
return;
}
- unique_ptr<eventInfo, uniqueDeleter<eventInfo> > toEnqueue(new eventInfo());
+ std::unique_ptr<eventInfo, uniqueDeleter<eventInfo> > toEnqueue(new eventInfo());
toEnqueue->eventBuff_ = new uint8_t[(sizeof(uint8_t) * eventLen) + 4];
// first 4 bytes is the event length
@@ -272,7 +264,7 @@
// it is probably a non-factor for the time being
}
-bool TFileTransport::swapEventBuffers(struct timeval* deadline) {
+bool TFileTransport::swapEventBuffers(const std::chrono::time_point<std::chrono::steady_clock> *deadline) {
bool swap;
Guard g(mutex_);
@@ -283,9 +275,9 @@
// return immediately if the transport is closing
swap = false;
} else {
- if (deadline != NULL) {
+ if (deadline != nullptr) {
// if we were handed a deadline time struct, do a timed wait
- notEmpty_.waitForTime(deadline);
+ notEmpty_.waitForTime(*deadline);
} else {
// just wait until the buffer gets an item
notEmpty_.wait();
@@ -344,8 +336,7 @@
}
// Figure out the next time by which a flush must take place
- struct timeval ts_next_flush;
- getNextFlushTime(&ts_next_flush);
+ auto ts_next_flush = getNextFlushTime();
uint32_t unflushed = 0;
while (1) {
@@ -371,7 +362,7 @@
if (swapEventBuffers(&ts_next_flush)) {
eventInfo* outEvent;
- while (NULL != (outEvent = dequeueBuffer_->getNext())) {
+ while (nullptr != (outEvent = dequeueBuffer_->getNext())) {
// Remove an event from the buffer and write it out to disk. If there is any IO error, for
// instance,
// the output file is unmounted or deleted, then this event is dropped. However, the writer
@@ -431,9 +422,9 @@
if (chunk1 != chunk2) {
// refetch the offset to keep in sync
offset_ = THRIFT_LSEEK(fd_, 0, SEEK_CUR);
- int32_t padding = (int32_t)((offset_ / chunkSize_ + 1) * chunkSize_ - offset_);
+ auto padding = (int32_t)((offset_ / chunkSize_ + 1) * chunkSize_ - offset_);
- uint8_t* zeros = new uint8_t[padding];
+ auto* zeros = new uint8_t[padding];
memset(zeros, '\0', padding);
boost::scoped_array<uint8_t> array(zeros);
if (-1 == ::write(fd_, zeros, padding)) {
@@ -498,17 +489,13 @@
if (forced_flush || unflushed > flushMaxBytes_) {
flush = true;
} else {
- struct timeval current_time;
- THRIFT_GETTIMEOFDAY(¤t_time, NULL);
- if (current_time.tv_sec > ts_next_flush.tv_sec
- || (current_time.tv_sec == ts_next_flush.tv_sec
- && current_time.tv_usec > ts_next_flush.tv_usec)) {
+ if (std::chrono::steady_clock::now() > ts_next_flush) {
if (unflushed > 0) {
flush = true;
} else {
// If there is no new data since the last fsync,
// don't perform the fsync, but do reset the timer.
- getNextFlushTime(&ts_next_flush);
+ ts_next_flush = getNextFlushTime();
}
}
}
@@ -517,7 +504,7 @@
// sync (force flush) file to disk
THRIFT_FSYNC(fd_);
unflushed = 0;
- getNextFlushTime(&ts_next_flush);
+ ts_next_flush = getNextFlushTime();
// notify anybody waiting for flush completion
if (forced_flush) {
@@ -600,7 +587,7 @@
memcpy(buf, currentEvent_->eventBuff_ + currentEvent_->eventBuffPos_, remaining);
}
delete (currentEvent_);
- currentEvent_ = NULL;
+ currentEvent_ = nullptr;
return remaining;
}
@@ -643,12 +630,12 @@
} else if (readTimeout_ == NO_TAIL_READ_TIMEOUT) {
// reset state
readState_.resetState(0);
- return NULL;
+ return nullptr;
} else if (readTimeout_ > 0) {
// timeout already expired once
if (readTries > 0) {
readState_.resetState(0);
- return NULL;
+ return nullptr;
} else {
THRIFT_SLEEP_USEC(readTimeout_ * 1000);
readTries++;
@@ -722,7 +709,7 @@
eventInfo* completeEvent = readState_.event_;
completeEvent->eventBuffPos_ = 0;
- readState_.event_ = NULL;
+ readState_.event_ = nullptr;
readState_.resetState(readState_.bufferPtr_);
// exit criteria
@@ -791,7 +778,7 @@
// pretty hosed at this stage, rewind the file back to the last successful
// point and punt on the error
readState_.resetState(readState_.lastDispatchPtr_);
- currentEvent_ = NULL;
+ currentEvent_ = nullptr;
char errorMsg[1024];
sprintf(errorMsg,
"TFileTransport: log file corrupted at offset: %lu",
@@ -840,7 +827,7 @@
off_t newOffset = off_t(chunk) * chunkSize_;
offset_ = ::THRIFT_LSEEK(fd_, newOffset, SEEK_SET);
readState_.resetAllValues();
- currentEvent_ = NULL;
+ currentEvent_ = nullptr;
if (offset_ == -1) {
GlobalOutput("TFileTransport: lseek error in seekToChunk");
throw TTransportException("TFileTransport: lseek error in seekToChunk");
@@ -854,7 +841,7 @@
shared_ptr<eventInfo> event;
while ((offset_ + readState_.bufferPtr_) < minEndOffset) {
event.reset(readEvent());
- if (event.get() == NULL) {
+ if (event.get() == nullptr) {
break;
}
}
@@ -916,15 +903,8 @@
}
}
-void TFileTransport::getNextFlushTime(struct timeval* ts_next_flush) {
- THRIFT_GETTIMEOFDAY(ts_next_flush, NULL);
-
- ts_next_flush->tv_usec += flushMaxUs_;
- if (ts_next_flush->tv_usec > 1000000) {
- long extra_secs = ts_next_flush->tv_usec / 1000000;
- ts_next_flush->tv_usec %= 1000000;
- ts_next_flush->tv_sec += extra_secs;
- }
+std::chrono::time_point<std::chrono::steady_clock> TFileTransport::getNextFlushTime() {
+ return std::chrono::steady_clock::now() + std::chrono::microseconds(flushMaxUs_);
}
TFileTransportBuffer::TFileTransportBuffer(uint32_t size)
@@ -938,7 +918,7 @@
delete buffer_[i];
}
delete[] buffer_;
- buffer_ = NULL;
+ buffer_ = nullptr;
}
}
@@ -963,7 +943,7 @@
return buffer_[readPoint_++];
} else {
// no more entries
- return NULL;
+ return nullptr;
}
}
@@ -997,7 +977,7 @@
inputTransport_(inputTransport) {
// default the output transport to a null transport (common case)
- outputTransport_ = shared_ptr<TNullTransport>(new TNullTransport());
+ outputTransport_ = std::make_shared<TNullTransport>();
}
TFileProcessor::TFileProcessor(shared_ptr<TProcessor> processor,
@@ -1010,7 +990,7 @@
inputTransport_(inputTransport) {
// default the output transport to a null transport (common case)
- outputTransport_ = shared_ptr<TNullTransport>(new TNullTransport());
+ outputTransport_ = std::make_shared<TNullTransport>();
}
TFileProcessor::TFileProcessor(shared_ptr<TProcessor> processor,
@@ -1040,7 +1020,7 @@
// bad form to use exceptions for flow control but there is really
// no other way around it
try {
- processor_->process(inputProtocol, outputProtocol, NULL);
+ processor_->process(inputProtocol, outputProtocol, nullptr);
numProcessed++;
if ((numEvents > 0) && (numProcessed == numEvents)) {
return;
@@ -1071,7 +1051,7 @@
// bad form to use exceptions for flow control but there is really
// no other way around it
try {
- processor_->process(inputProtocol, outputProtocol, NULL);
+ processor_->process(inputProtocol, outputProtocol, nullptr);
if (curChunk != inputTransport_->getCurChunk()) {
break;
}
diff --git a/lib/cpp/src/thrift/transport/TFileTransport.h b/lib/cpp/src/thrift/transport/TFileTransport.h
index d6da436..0df5cf9 100644
--- a/lib/cpp/src/thrift/transport/TFileTransport.h
+++ b/lib/cpp/src/thrift/transport/TFileTransport.h
@@ -24,15 +24,13 @@
#include <thrift/Thrift.h>
#include <thrift/TProcessor.h>
+#include <atomic>
#include <string>
#include <stdio.h>
-#include <boost/atomic.hpp>
-#include <thrift/stdcxx.h>
-
#include <thrift/concurrency/Mutex.h>
#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/concurrency/Thread.h>
namespace apache {
@@ -50,7 +48,7 @@
uint32_t eventSize_;
uint32_t eventBuffPos_;
- eventInfo() : eventBuff_(NULL), eventSize_(0), eventBuffPos_(0){};
+ eventInfo() : eventBuff_(nullptr), eventSize_(0), eventBuffPos_(0){};
~eventInfo() {
if (eventBuff_) {
delete[] eventBuff_;
@@ -87,7 +85,7 @@
if (event_) {
delete (event_);
}
- event_ = 0;
+ event_ = nullptr;
}
inline uint32_t getEventSize() {
@@ -96,7 +94,7 @@
}
readState() {
- event_ = 0;
+ event_ = nullptr;
resetAllValues();
}
@@ -176,24 +174,24 @@
class TFileTransport : public TFileReaderTransport, public TFileWriterTransport {
public:
TFileTransport(std::string path, bool readOnly = false);
- ~TFileTransport();
+ ~TFileTransport() override;
// TODO: what is the correct behaviour for this?
// the log file is generally always open
- bool isOpen() { return true; }
+ bool isOpen() const override { return true; }
void write(const uint8_t* buf, uint32_t len);
- void flush();
+ void flush() override;
uint32_t readAll(uint8_t* buf, uint32_t len);
uint32_t read(uint8_t* buf, uint32_t len);
- bool peek();
+ bool peek() override;
// log-file specific functions
- void seekToChunk(int32_t chunk);
- void seekToEnd();
- uint32_t getNumChunks();
- uint32_t getCurChunk();
+ void seekToChunk(int32_t chunk) override;
+ void seekToEnd() override;
+ uint32_t getNumChunks() override;
+ uint32_t getCurChunk() override;
// for changing the output file
void resetOutputFile(int fd, std::string filename, off_t offset);
@@ -208,15 +206,15 @@
static const int32_t TAIL_READ_TIMEOUT = -1;
static const int32_t NO_TAIL_READ_TIMEOUT = 0;
- void setReadTimeout(int32_t readTimeout) { readTimeout_ = readTimeout; }
- int32_t getReadTimeout() { return readTimeout_; }
+ void setReadTimeout(int32_t readTimeout) override { readTimeout_ = readTimeout; }
+ int32_t getReadTimeout() override { return readTimeout_; }
- void setChunkSize(uint32_t chunkSize) {
+ void setChunkSize(uint32_t chunkSize) override {
if (chunkSize) {
chunkSize_ = chunkSize;
}
}
- uint32_t getChunkSize() { return chunkSize_; }
+ uint32_t getChunkSize() override { return chunkSize_; }
void setEventBufferSize(uint32_t bufferSize) {
if (bufferAndThreadInitialized_) {
@@ -262,20 +260,20 @@
* We cannot use TVirtualTransport to provide these, since we need to inherit
* virtually from TTransport.
*/
- virtual uint32_t read_virt(uint8_t* buf, uint32_t len) { return this->read(buf, len); }
- virtual uint32_t readAll_virt(uint8_t* buf, uint32_t len) { return this->readAll(buf, len); }
- virtual void write_virt(const uint8_t* buf, uint32_t len) { this->write(buf, len); }
+ uint32_t read_virt(uint8_t* buf, uint32_t len) override { return this->read(buf, len); }
+ uint32_t readAll_virt(uint8_t* buf, uint32_t len) override { return this->readAll(buf, len); }
+ void write_virt(const uint8_t* buf, uint32_t len) override { this->write(buf, len); }
private:
// helper functions for writing to a file
void enqueueEvent(const uint8_t* buf, uint32_t eventLen);
- bool swapEventBuffers(struct timeval* deadline);
+ bool swapEventBuffers(const std::chrono::time_point<std::chrono::steady_clock> *deadline);
bool initBufferAndWriteThread();
// control for writer thread
static void* startWriterThread(void* ptr) {
static_cast<TFileTransport*>(ptr)->writerThread();
- return NULL;
+ return nullptr;
}
void writerThread();
@@ -288,7 +286,7 @@
// Utility functions
void openLogFile();
- void getNextFlushTime(struct timeval* ts_next_flush);
+ std::chrono::time_point<std::chrono::steady_clock> getNextFlushTime();
// Class variables
readState readState_;
@@ -338,8 +336,8 @@
static const uint32_t DEFAULT_WRITER_THREAD_SLEEP_TIME_US = 60 * 1000 * 1000;
// writer thread
- apache::thrift::concurrency::PlatformThreadFactory threadFactory_;
- stdcxx::shared_ptr<apache::thrift::concurrency::Thread> writerThread_;
+ apache::thrift::concurrency::ThreadFactory threadFactory_;
+ std::shared_ptr<apache::thrift::concurrency::Thread> writerThread_;
// buffers to hold data before it is flushed. Each element of the buffer stores a msg that
// needs to be written to the file. The buffers are swapped by the writer thread.
@@ -348,11 +346,11 @@
// conditions used to block when the buffer is full or empty
Monitor notFull_, notEmpty_;
- boost::atomic<bool> closing_;
+ std::atomic<bool> closing_;
// To keep track of whether the buffer has been flushed
Monitor flushed_;
- boost::atomic<bool> forceFlush_;
+ std::atomic<bool> forceFlush_;
// Mutex that is grabbed when enqueueing and swapping the read/write buffers
Mutex mutex_;
@@ -390,14 +388,14 @@
* @param protocolFactory protocol factory
* @param inputTransport file transport
*/
- TFileProcessor(stdcxx::shared_ptr<TProcessor> processor,
- stdcxx::shared_ptr<TProtocolFactory> protocolFactory,
- stdcxx::shared_ptr<TFileReaderTransport> inputTransport);
+ TFileProcessor(std::shared_ptr<TProcessor> processor,
+ std::shared_ptr<TProtocolFactory> protocolFactory,
+ std::shared_ptr<TFileReaderTransport> inputTransport);
- TFileProcessor(stdcxx::shared_ptr<TProcessor> processor,
- stdcxx::shared_ptr<TProtocolFactory> inputProtocolFactory,
- stdcxx::shared_ptr<TProtocolFactory> outputProtocolFactory,
- stdcxx::shared_ptr<TFileReaderTransport> inputTransport);
+ TFileProcessor(std::shared_ptr<TProcessor> processor,
+ std::shared_ptr<TProtocolFactory> inputProtocolFactory,
+ std::shared_ptr<TProtocolFactory> outputProtocolFactory,
+ std::shared_ptr<TFileReaderTransport> inputTransport);
/**
* Constructor
@@ -407,10 +405,10 @@
* @param inputTransport input file transport
* @param output output transport
*/
- TFileProcessor(stdcxx::shared_ptr<TProcessor> processor,
- stdcxx::shared_ptr<TProtocolFactory> protocolFactory,
- stdcxx::shared_ptr<TFileReaderTransport> inputTransport,
- stdcxx::shared_ptr<TTransport> outputTransport);
+ TFileProcessor(std::shared_ptr<TProcessor> processor,
+ std::shared_ptr<TProtocolFactory> protocolFactory,
+ std::shared_ptr<TFileReaderTransport> inputTransport,
+ std::shared_ptr<TTransport> outputTransport);
/**
* processes events from the file
@@ -427,11 +425,11 @@
void processChunk();
private:
- stdcxx::shared_ptr<TProcessor> processor_;
- stdcxx::shared_ptr<TProtocolFactory> inputProtocolFactory_;
- stdcxx::shared_ptr<TProtocolFactory> outputProtocolFactory_;
- stdcxx::shared_ptr<TFileReaderTransport> inputTransport_;
- stdcxx::shared_ptr<TTransport> outputTransport_;
+ std::shared_ptr<TProcessor> processor_;
+ std::shared_ptr<TProtocolFactory> inputProtocolFactory_;
+ std::shared_ptr<TProtocolFactory> outputProtocolFactory_;
+ std::shared_ptr<TFileReaderTransport> inputTransport_;
+ std::shared_ptr<TTransport> outputTransport_;
};
}
}
diff --git a/lib/cpp/src/thrift/transport/THeaderTransport.cpp b/lib/cpp/src/thrift/transport/THeaderTransport.cpp
index ea16591..b582d8d 100644
--- a/lib/cpp/src/thrift/transport/THeaderTransport.cpp
+++ b/lib/cpp/src/thrift/transport/THeaderTransport.cpp
@@ -22,7 +22,6 @@
#include <thrift/protocol/TProtocolTypes.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TCompactProtocol.h>
-#include <thrift/stdcxx.h>
#include <limits>
#include <utility>
@@ -37,7 +36,7 @@
namespace apache {
namespace thrift {
-using stdcxx::shared_ptr;
+using std::shared_ptr;
namespace transport {
@@ -198,7 +197,7 @@
readHeaders_.clear(); // Clear out any previous headers.
// skip over already processed magic(4), seqId(4), headerSize(2)
- uint8_t* ptr = reinterpret_cast<uint8_t*>(rBuf_.get() + 10);
+ auto* ptr = reinterpret_cast<uint8_t*>(rBuf_.get() + 10);
// Catch integer overflow, check for reasonable header size
if (headerSize >= 16384) {
@@ -276,9 +275,9 @@
stream.avail_in = sz;
// Setting these to 0 means use the default free/alloc functions
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
+ stream.zalloc = (alloc_func)nullptr;
+ stream.zfree = (free_func)nullptr;
+ stream.opaque = (voidpf)nullptr;
err = inflateInit(&stream);
if (err != Z_OK) {
throw TApplicationException(TApplicationException::MISSING_RESULT,
@@ -318,7 +317,7 @@
void THeaderTransport::resizeTransformBuffer(uint32_t additionalSize) {
if (tBufSize_ < wBufSize_ + DEFAULT_BUFFER_SIZE) {
uint32_t new_size = wBufSize_ + DEFAULT_BUFFER_SIZE + additionalSize;
- uint8_t* new_buf = new uint8_t[new_size];
+ auto* new_buf = new uint8_t[new_size];
tBuf_.reset(new_buf);
tBufSize_ = new_size;
}
@@ -338,9 +337,9 @@
stream.next_in = ptr;
stream.avail_in = sz;
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
+ stream.zalloc = (alloc_func)nullptr;
+ stream.zfree = (free_func)nullptr;
+ stream.opaque = (voidpf)nullptr;
err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
if (err != Z_OK) {
throw TTransportException(TTransportException::CORRUPTED_DATA,
@@ -390,7 +389,7 @@
* Automatically advances ptr to after the written portion
*/
void THeaderTransport::writeString(uint8_t*& ptr, const string& str) {
- int32_t strLen = safe_numeric_cast<int32_t>(str.length());
+ auto strLen = safe_numeric_cast<int32_t>(str.length());
ptr += writeVarint32(strLen, ptr);
memcpy(ptr, str.c_str(), strLen); // no need to write \0
ptr += strLen;
@@ -485,7 +484,7 @@
// write info headers
// for now only write kv-headers
- int32_t headerCount = safe_numeric_cast<int32_t>(writeHeaders_.size());
+ auto headerCount = safe_numeric_cast<int32_t>(writeHeaders_.size());
if (headerCount > 0) {
pkt += writeVarint32(infoIdType::KEYVALUE, pkt);
// Write key-value headers count
@@ -527,7 +526,7 @@
outTransport_->write(pktStart, szHbo - haveBytes + 4);
outTransport_->write(wBuf_.get(), haveBytes);
} else if (clientType == THRIFT_FRAMED_BINARY || clientType == THRIFT_FRAMED_COMPACT) {
- uint32_t szHbo = (uint32_t)haveBytes;
+ auto szHbo = (uint32_t)haveBytes;
uint32_t szNbo = htonl(szHbo);
outTransport_->write(reinterpret_cast<uint8_t*>(&szNbo), 4);
diff --git a/lib/cpp/src/thrift/transport/THeaderTransport.h b/lib/cpp/src/thrift/transport/THeaderTransport.h
index 1a2c8e0..d1e9d43 100644
--- a/lib/cpp/src/thrift/transport/THeaderTransport.h
+++ b/lib/cpp/src/thrift/transport/THeaderTransport.h
@@ -34,7 +34,6 @@
#endif
#include <boost/scoped_array.hpp>
-#include <thrift/stdcxx.h>
#include <thrift/protocol/TProtocolTypes.h>
#include <thrift/transport/TBufferTransports.h>
@@ -75,7 +74,7 @@
static const int THRIFT_MAX_VARINT32_BYTES = 5;
/// Use default buffer sizes.
- explicit THeaderTransport(const stdcxx::shared_ptr<TTransport>& transport)
+ explicit THeaderTransport(const std::shared_ptr<TTransport>& transport)
: TVirtualTransport(transport),
outTransport_(transport),
protoId(T_COMPACT_PROTOCOL),
@@ -83,13 +82,13 @@
seqId(0),
flags(0),
tBufSize_(0),
- tBuf_(NULL) {
+ tBuf_(nullptr) {
if (!transport_) throw std::invalid_argument("transport is empty");
initBuffers();
}
- THeaderTransport(const stdcxx::shared_ptr<TTransport> inTransport,
- const stdcxx::shared_ptr<TTransport> outTransport)
+ THeaderTransport(const std::shared_ptr<TTransport> inTransport,
+ const std::shared_ptr<TTransport> outTransport)
: TVirtualTransport(inTransport),
outTransport_(outTransport),
protoId(T_COMPACT_PROTOCOL),
@@ -97,14 +96,14 @@
seqId(0),
flags(0),
tBufSize_(0),
- tBuf_(NULL) {
+ tBuf_(nullptr) {
if (!transport_) throw std::invalid_argument("inTransport is empty");
if (!outTransport_) throw std::invalid_argument("outTransport is empty");
initBuffers();
}
- virtual uint32_t readSlow(uint8_t* buf, uint32_t len);
- virtual void flush();
+ uint32_t readSlow(uint8_t* buf, uint32_t len) override;
+ void flush() override;
void resizeTransformBuffer(uint32_t additionalSize = 0);
@@ -176,17 +175,17 @@
* Returns true if a frame was read successfully, or false on EOF.
* (Raises a TTransportException if EOF occurs after a partial frame.)
*/
- virtual bool readFrame();
+ bool readFrame() override;
void ensureReadBuffer(uint32_t sz);
uint32_t getWriteBytes();
void initBuffers() {
- setReadBuffer(NULL, 0);
+ setReadBuffer(nullptr, 0);
setWriteBuffer(wBuf_.get(), wBufSize_);
}
- stdcxx::shared_ptr<TTransport> outTransport_;
+ std::shared_ptr<TTransport> outTransport_;
// 0 and 16th bits must be 0 to differentiate from framed & unframed
static const uint32_t HEADER_MAGIC = 0x0FFF0000;
@@ -258,15 +257,15 @@
*/
class THeaderTransportFactory : public TTransportFactory {
public:
- THeaderTransportFactory() {}
+ THeaderTransportFactory() = default;
- virtual ~THeaderTransportFactory() {}
+ ~THeaderTransportFactory() override = default;
/**
* Wraps the transport into a header one.
*/
- virtual stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> trans) {
- return stdcxx::shared_ptr<TTransport>(new THeaderTransport(trans));
+ std::shared_ptr<TTransport> getTransport(std::shared_ptr<TTransport> trans) override {
+ return std::shared_ptr<TTransport>(new THeaderTransport(trans));
}
};
}
diff --git a/lib/cpp/src/thrift/transport/THttpClient.cpp b/lib/cpp/src/thrift/transport/THttpClient.cpp
index afd02a8..04566c9 100644
--- a/lib/cpp/src/thrift/transport/THttpClient.cpp
+++ b/lib/cpp/src/thrift/transport/THttpClient.cpp
@@ -32,24 +32,23 @@
namespace thrift {
namespace transport {
-THttpClient::THttpClient(stdcxx::shared_ptr<TTransport> transport,
+THttpClient::THttpClient(std::shared_ptr<TTransport> transport,
std::string host,
std::string path)
: THttpTransport(transport), host_(host), path_(path) {
}
THttpClient::THttpClient(string host, int port, string path)
- : THttpTransport(stdcxx::shared_ptr<TTransport>(new TSocket(host, port))),
+ : THttpTransport(std::shared_ptr<TTransport>(new TSocket(host, port))),
host_(host),
path_(path) {
}
-THttpClient::~THttpClient() {
-}
+THttpClient::~THttpClient() = default;
void THttpClient::parseHeader(char* header) {
char* colon = strchr(header, ':');
- if (colon == NULL) {
+ if (colon == nullptr) {
return;
}
char* value = colon + 1;
@@ -68,7 +67,7 @@
char* http = status;
char* code = strchr(http, ' ');
- if (code == NULL) {
+ if (code == nullptr) {
throw TTransportException(string("Bad Status: ") + status);
}
@@ -77,7 +76,7 @@
};
char* msg = strchr(code, ' ');
- if (msg == NULL) {
+ if (msg == nullptr) {
throw TTransportException(string("Bad Status: ") + status);
}
*msg = '\0';
diff --git a/lib/cpp/src/thrift/transport/THttpClient.h b/lib/cpp/src/thrift/transport/THttpClient.h
index 96fd5b8..fdca505 100644
--- a/lib/cpp/src/thrift/transport/THttpClient.h
+++ b/lib/cpp/src/thrift/transport/THttpClient.h
@@ -28,20 +28,20 @@
class THttpClient : public THttpTransport {
public:
- THttpClient(stdcxx::shared_ptr<TTransport> transport, std::string host, std::string path = "");
+ THttpClient(std::shared_ptr<TTransport> transport, std::string host, std::string path = "");
THttpClient(std::string host, int port, std::string path = "");
- virtual ~THttpClient();
+ ~THttpClient() override;
- virtual void flush();
+ void flush() override;
protected:
std::string host_;
std::string path_;
- virtual void parseHeader(char* header);
- virtual bool parseStatusLine(char* status);
+ void parseHeader(char* header) override;
+ bool parseStatusLine(char* status) override;
};
}
}
diff --git a/lib/cpp/src/thrift/transport/THttpServer.cpp b/lib/cpp/src/thrift/transport/THttpServer.cpp
index 2f48cf6..94ac681 100644
--- a/lib/cpp/src/thrift/transport/THttpServer.cpp
+++ b/lib/cpp/src/thrift/transport/THttpServer.cpp
@@ -34,11 +34,10 @@
namespace thrift {
namespace transport {
-THttpServer::THttpServer(stdcxx::shared_ptr<TTransport> transport) : THttpTransport(transport) {
+THttpServer::THttpServer(std::shared_ptr<TTransport> transport) : THttpTransport(transport) {
}
-THttpServer::~THttpServer() {
-}
+THttpServer::~THttpServer() = default;
#if defined(_MSC_VER) || defined(__MINGW32__)
#define THRIFT_GMTIME(TM, TIME) gmtime_s(&TM, &TIME)
@@ -52,14 +51,14 @@
void THttpServer::parseHeader(char* header) {
char* colon = strchr(header, ':');
- if (colon == NULL) {
+ if (colon == nullptr) {
return;
}
size_t sz = colon - header;
char* value = colon + 1;
if (THRIFT_strncasecmp(header, "Transfer-Encoding", sz) == 0) {
- if (THRIFT_strcasestr(value, "chunked") != NULL) {
+ if (THRIFT_strcasestr(value, "chunked") != nullptr) {
chunked_ = true;
}
} else if (THRIFT_strncasecmp(header, "Content-length", sz) == 0) {
@@ -74,7 +73,7 @@
char* method = status;
char* path = strchr(method, ' ');
- if (path == NULL) {
+ if (path == nullptr) {
throw TTransportException(string("Bad Status: ") + status);
}
@@ -83,7 +82,7 @@
};
char* http = strchr(path, ' ');
- if (http == NULL) {
+ if (http == nullptr) {
throw TTransportException(string("Bad Status: ") + status);
}
*http = '\0';
@@ -149,7 +148,7 @@
= {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
char buff[128];
- time_t t = time(NULL);
+ time_t t = time(nullptr);
struct tm tmb;
THRIFT_GMTIME(tmb, t);
diff --git a/lib/cpp/src/thrift/transport/THttpServer.h b/lib/cpp/src/thrift/transport/THttpServer.h
index 086dd6f..0e83399 100644
--- a/lib/cpp/src/thrift/transport/THttpServer.h
+++ b/lib/cpp/src/thrift/transport/THttpServer.h
@@ -28,16 +28,16 @@
class THttpServer : public THttpTransport {
public:
- THttpServer(stdcxx::shared_ptr<TTransport> transport);
+ THttpServer(std::shared_ptr<TTransport> transport);
- virtual ~THttpServer();
+ ~THttpServer() override;
- virtual void flush();
+ void flush() override;
protected:
void readHeaders();
- virtual void parseHeader(char* header);
- virtual bool parseStatusLine(char* status);
+ void parseHeader(char* header) override;
+ bool parseStatusLine(char* status) override;
std::string getTimeRFC1123();
};
@@ -46,15 +46,15 @@
*/
class THttpServerTransportFactory : public TTransportFactory {
public:
- THttpServerTransportFactory() {}
+ THttpServerTransportFactory() = default;
- virtual ~THttpServerTransportFactory() {}
+ ~THttpServerTransportFactory() override = default;
/**
* Wraps the transport into a buffered one.
*/
- virtual stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> trans) {
- return stdcxx::shared_ptr<TTransport>(new THttpServer(trans));
+ std::shared_ptr<TTransport> getTransport(std::shared_ptr<TTransport> trans) override {
+ return std::shared_ptr<TTransport>(new THttpServer(trans));
}
};
}
diff --git a/lib/cpp/src/thrift/transport/THttpTransport.cpp b/lib/cpp/src/thrift/transport/THttpTransport.cpp
index 4ccb4d3..aea2b28 100644
--- a/lib/cpp/src/thrift/transport/THttpTransport.cpp
+++ b/lib/cpp/src/thrift/transport/THttpTransport.cpp
@@ -31,7 +31,7 @@
const char* THttpTransport::CRLF = "\r\n";
const int THttpTransport::CRLF_LEN = 2;
-THttpTransport::THttpTransport(stdcxx::shared_ptr<TTransport> transport)
+THttpTransport::THttpTransport(std::shared_ptr<TTransport> transport)
: transport_(transport),
origin_(""),
readHeaders_(true),
@@ -39,7 +39,7 @@
chunkedDone_(false),
chunkSize_(0),
contentLength_(0),
- httpBuf_(NULL),
+ httpBuf_(nullptr),
httpPos_(0),
httpBufLen_(0),
httpBufSize_(1024) {
@@ -48,14 +48,14 @@
void THttpTransport::init() {
httpBuf_ = (char*)std::malloc(httpBufSize_ + 1);
- if (httpBuf_ == NULL) {
+ if (httpBuf_ == nullptr) {
throw std::bad_alloc();
}
httpBuf_[httpBufLen_] = '\0';
}
THttpTransport::~THttpTransport() {
- if (httpBuf_ != NULL) {
+ if (httpBuf_ != nullptr) {
std::free(httpBuf_);
}
}
@@ -132,7 +132,7 @@
uint32_t THttpTransport::parseChunkSize(char* line) {
char* semi = strchr(line, ';');
- if (semi != NULL) {
+ if (semi != nullptr) {
*semi = '\0';
}
uint32_t size = 0;
@@ -166,12 +166,12 @@
char* THttpTransport::readLine() {
while (true) {
- char* eol = NULL;
+ char* eol = nullptr;
eol = strstr(httpBuf_ + httpPos_, CRLF);
// No CRLF yet?
- if (eol == NULL) {
+ if (eol == nullptr) {
// Shift whatever we have now to front and refill
shift();
refill();
@@ -203,7 +203,7 @@
if (avail <= (httpBufSize_ / 4)) {
httpBufSize_ *= 2;
char* tmpBuf = (char*)std::realloc(httpBuf_, httpBufSize_ + 1);
- if (tmpBuf == NULL) {
+ if (tmpBuf == nullptr) {
throw std::bad_alloc();
}
httpBuf_ = tmpBuf;
@@ -257,7 +257,7 @@
writeBuffer_.write(buf, len);
}
-const std::string THttpTransport::getOrigin() {
+const std::string THttpTransport::getOrigin() const {
std::ostringstream oss;
if (!origin_.empty()) {
oss << origin_ << ", ";
diff --git a/lib/cpp/src/thrift/transport/THttpTransport.h b/lib/cpp/src/thrift/transport/THttpTransport.h
index 3fa80f8..75f0d8c 100644
--- a/lib/cpp/src/thrift/transport/THttpTransport.h
+++ b/lib/cpp/src/thrift/transport/THttpTransport.h
@@ -36,30 +36,30 @@
*/
class THttpTransport : public TVirtualTransport<THttpTransport> {
public:
- THttpTransport(stdcxx::shared_ptr<TTransport> transport);
+ THttpTransport(std::shared_ptr<TTransport> transport);
- virtual ~THttpTransport();
+ ~THttpTransport() override;
- void open() { transport_->open(); }
+ void open() override { transport_->open(); }
- bool isOpen() { return transport_->isOpen(); }
+ bool isOpen() const override { return transport_->isOpen(); }
- bool peek() { return transport_->peek(); }
+ bool peek() override { return transport_->peek(); }
- void close() { transport_->close(); }
+ void close() override { transport_->close(); }
uint32_t read(uint8_t* buf, uint32_t len);
- uint32_t readEnd();
+ uint32_t readEnd() override;
void write(const uint8_t* buf, uint32_t len);
- virtual void flush() = 0;
+ void flush() override = 0;
- virtual const std::string getOrigin();
+ const std::string getOrigin() const override;
protected:
- stdcxx::shared_ptr<TTransport> transport_;
+ std::shared_ptr<TTransport> transport_;
std::string origin_;
TMemoryBuffer writeBuffer_;
diff --git a/lib/cpp/src/thrift/transport/TNonblockingSSLServerSocket.cpp b/lib/cpp/src/thrift/transport/TNonblockingSSLServerSocket.cpp
index da83bea..adec5d0 100644
--- a/lib/cpp/src/thrift/transport/TNonblockingSSLServerSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TNonblockingSSLServerSocket.cpp
@@ -27,14 +27,14 @@
/**
* Nonblocking SSL server socket implementation.
*/
-TNonblockingSSLServerSocket::TNonblockingSSLServerSocket(int port, stdcxx::shared_ptr<TSSLSocketFactory> factory)
+TNonblockingSSLServerSocket::TNonblockingSSLServerSocket(int port, std::shared_ptr<TSSLSocketFactory> factory)
: TNonblockingServerSocket(port), factory_(factory) {
factory_->server(true);
}
TNonblockingSSLServerSocket::TNonblockingSSLServerSocket(const std::string& address,
int port,
- stdcxx::shared_ptr<TSSLSocketFactory> factory)
+ std::shared_ptr<TSSLSocketFactory> factory)
: TNonblockingServerSocket(address, port), factory_(factory) {
factory_->server(true);
}
@@ -42,13 +42,13 @@
TNonblockingSSLServerSocket::TNonblockingSSLServerSocket(int port,
int sendTimeout,
int recvTimeout,
- stdcxx::shared_ptr<TSSLSocketFactory> factory)
+ std::shared_ptr<TSSLSocketFactory> factory)
: TNonblockingServerSocket(port, sendTimeout, recvTimeout), factory_(factory) {
factory_->server(true);
}
-stdcxx::shared_ptr<TSocket> TNonblockingSSLServerSocket::createSocket(THRIFT_SOCKET client) {
- stdcxx::shared_ptr<TSSLSocket> tSSLSocket;
+std::shared_ptr<TSocket> TNonblockingSSLServerSocket::createSocket(THRIFT_SOCKET client) {
+ std::shared_ptr<TSSLSocket> tSSLSocket;
tSSLSocket = factory_->createSocket(client);
tSSLSocket->setLibeventSafe();
return tSSLSocket;
diff --git a/lib/cpp/src/thrift/transport/TNonblockingSSLServerSocket.h b/lib/cpp/src/thrift/transport/TNonblockingSSLServerSocket.h
index 7aaff53..a38bf12 100644
--- a/lib/cpp/src/thrift/transport/TNonblockingSSLServerSocket.h
+++ b/lib/cpp/src/thrift/transport/TNonblockingSSLServerSocket.h
@@ -21,7 +21,6 @@
#define _THRIFT_TRANSPORT_TNONBLOCKINGSSLSERVERSOCKET_H_ 1
#include <thrift/transport/TNonblockingServerSocket.h>
-#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@@ -40,7 +39,7 @@
* @param port Listening port
* @param factory SSL socket factory implementation
*/
- TNonblockingSSLServerSocket(int port, stdcxx::shared_ptr<TSSLSocketFactory> factory);
+ TNonblockingSSLServerSocket(int port, std::shared_ptr<TSSLSocketFactory> factory);
/**
* Constructor. Binds to the specified address.
@@ -51,7 +50,7 @@
*/
TNonblockingSSLServerSocket(const std::string& address,
int port,
- stdcxx::shared_ptr<TSSLSocketFactory> factory);
+ std::shared_ptr<TSSLSocketFactory> factory);
/**
* Constructor. Binds to all interfaces.
@@ -64,11 +63,11 @@
TNonblockingSSLServerSocket(int port,
int sendTimeout,
int recvTimeout,
- stdcxx::shared_ptr<TSSLSocketFactory> factory);
+ std::shared_ptr<TSSLSocketFactory> factory);
protected:
- stdcxx::shared_ptr<TSocket> createSocket(THRIFT_SOCKET socket);
- stdcxx::shared_ptr<TSSLSocketFactory> factory_;
+ std::shared_ptr<TSocket> createSocket(THRIFT_SOCKET socket) override;
+ std::shared_ptr<TSSLSocketFactory> factory_;
};
}
}
diff --git a/lib/cpp/src/thrift/transport/TNonblockingServerSocket.cpp b/lib/cpp/src/thrift/transport/TNonblockingServerSocket.cpp
index cca52a4..9902b90 100644
--- a/lib/cpp/src/thrift/transport/TNonblockingServerSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TNonblockingServerSocket.cpp
@@ -20,6 +20,7 @@
#include <thrift/thrift-config.h>
#include <cstring>
+#include <memory>
#include <stdexcept>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
@@ -74,7 +75,7 @@
namespace transport {
using std::string;
-using stdcxx::shared_ptr;
+using std::shared_ptr;
TNonblockingServerSocket::TNonblockingServerSocket(int port)
: port_(port),
@@ -193,7 +194,7 @@
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
// If address is not specified use wildcard address (NULL)
- TGetAddrInfoWrapper info(address_.empty() ? NULL : &address_[0], port, &hints);
+ TGetAddrInfoWrapper info(address_.empty() ? nullptr : &address_[0], port, &hints);
error = info.init();
if (error) {
@@ -206,13 +207,13 @@
// Pick the ipv6 address first since ipv4 addresses can be mapped
// into ipv6 space.
for (res = info.res(); res; res = res->ai_next) {
- if (res->ai_family == AF_INET6 || res->ai_next == NULL)
+ if (res->ai_family == AF_INET6 || res->ai_next == nullptr)
break;
}
if (!path_.empty()) {
serverSocket_ = socket(PF_UNIX, SOCK_STREAM, IPPROTO_IP);
- } else if (res != NULL) {
+ } else if (res != nullptr) {
serverSocket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
}
@@ -372,7 +373,7 @@
// Unix Domain Socket
size_t len = path_.size() + 1;
- if (len > sizeof(((sockaddr_un*)NULL)->sun_path)) {
+ if (len > sizeof(((sockaddr_un*)nullptr)->sun_path)) {
errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TSocket::listen() Unix Domain socket path too long", errno_copy);
throw TTransportException(TTransportException::NOT_OPEN,
@@ -384,7 +385,7 @@
address.sun_family = AF_UNIX;
memcpy(address.sun_path, path_.c_str(), len);
- socklen_t structlen = static_cast<socklen_t>(sizeof(address));
+ auto structlen = static_cast<socklen_t>(sizeof(address));
if (!address.sun_path[0]) { // abstract namespace socket
#ifdef __linux__
@@ -428,10 +429,10 @@
GlobalOutput.perror("TNonblockingServerSocket::getPort() getsockname() ", errno_copy);
} else {
if (sa.ss_family == AF_INET6) {
- const struct sockaddr_in6* sin = reinterpret_cast<const struct sockaddr_in6*>(&sa);
+ const auto* sin = reinterpret_cast<const struct sockaddr_in6*>(&sa);
listenPort_ = ntohs(sin->sin6_port);
} else {
- const struct sockaddr_in* sin = reinterpret_cast<const struct sockaddr_in*>(&sa);
+ const auto* sin = reinterpret_cast<const struct sockaddr_in*>(&sa);
listenPort_ = ntohs(sin->sin_port);
}
}
@@ -532,7 +533,7 @@
}
shared_ptr<TSocket> TNonblockingServerSocket::createSocket(THRIFT_SOCKET clientSocket) {
- return shared_ptr<TSocket>(new TSocket(clientSocket));
+ return std::make_shared<TSocket>(clientSocket);
}
void TNonblockingServerSocket::close() {
diff --git a/lib/cpp/src/thrift/transport/TNonblockingServerSocket.h b/lib/cpp/src/thrift/transport/TNonblockingServerSocket.h
index 1d33239..a68c28d 100644
--- a/lib/cpp/src/thrift/transport/TNonblockingServerSocket.h
+++ b/lib/cpp/src/thrift/transport/TNonblockingServerSocket.h
@@ -22,7 +22,6 @@
#include <thrift/transport/TNonblockingServerTransport.h>
#include <thrift/transport/PlatformSocket.h>
-#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@@ -37,7 +36,7 @@
*/
class TNonblockingServerSocket : public TNonblockingServerTransport {
public:
- typedef apache::thrift::stdcxx::function<void(THRIFT_SOCKET fd)> socket_func_t;
+ typedef std::function<void(THRIFT_SOCKET fd)> socket_func_t;
const static int DEFAULT_BACKLOG = 1024;
@@ -72,7 +71,7 @@
*/
TNonblockingServerSocket(const std::string& path);
- virtual ~TNonblockingServerSocket();
+ ~TNonblockingServerSocket() override;
void setSendTimeout(int sendTimeout);
void setRecvTimeout(int recvTimeout);
@@ -98,18 +97,18 @@
// socket, this is the place to do it.
void setAcceptCallback(const socket_func_t& acceptCallback) { acceptCallback_ = acceptCallback; }
- THRIFT_SOCKET getSocketFD() { return serverSocket_; }
+ THRIFT_SOCKET getSocketFD() override { return serverSocket_; }
- int getPort();
+ int getPort() override;
- int getListenPort();
+ int getListenPort() override;
- void listen();
- void close();
+ void listen() override;
+ void close() override;
protected:
- apache::thrift::stdcxx::shared_ptr<TSocket> acceptImpl();
- virtual apache::thrift::stdcxx::shared_ptr<TSocket> createSocket(THRIFT_SOCKET client);
+ std::shared_ptr<TSocket> acceptImpl() override;
+ virtual std::shared_ptr<TSocket> createSocket(THRIFT_SOCKET client);
private:
int port_;
diff --git a/lib/cpp/src/thrift/transport/TNonblockingServerTransport.h b/lib/cpp/src/thrift/transport/TNonblockingServerTransport.h
index c32a051..f811328 100644
--- a/lib/cpp/src/thrift/transport/TNonblockingServerTransport.h
+++ b/lib/cpp/src/thrift/transport/TNonblockingServerTransport.h
@@ -22,7 +22,6 @@
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportException.h>
-#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@@ -36,7 +35,7 @@
*/
class TNonblockingServerTransport {
public:
- virtual ~TNonblockingServerTransport() {}
+ virtual ~TNonblockingServerTransport() = default;
/**
* Starts the server transport listening for new connections. Prior to this
@@ -56,8 +55,8 @@
* @return A new TTransport object
* @throws TTransportException if there is an error
*/
- stdcxx::shared_ptr<TSocket> accept() {
- stdcxx::shared_ptr<TSocket> result = acceptImpl();
+ std::shared_ptr<TSocket> accept() {
+ std::shared_ptr<TSocket> result = acceptImpl();
if (!result) {
throw TTransportException("accept() may not return NULL");
}
@@ -83,7 +82,7 @@
virtual void close() = 0;
protected:
- TNonblockingServerTransport() {}
+ TNonblockingServerTransport() = default;
/**
* Subclasses should implement this function for accept.
@@ -91,7 +90,7 @@
* @return A newly allocated TTransport object
* @throw TTransportException If an error occurs
*/
- virtual stdcxx::shared_ptr<TSocket> acceptImpl() = 0;
+ virtual std::shared_ptr<TSocket> acceptImpl() = 0;
};
}
diff --git a/lib/cpp/src/thrift/transport/TPipe.cpp b/lib/cpp/src/thrift/transport/TPipe.cpp
index 8a84457..72af4fc 100644
--- a/lib/cpp/src/thrift/transport/TPipe.cpp
+++ b/lib/cpp/src/thrift/transport/TPipe.cpp
@@ -254,7 +254,7 @@
//---------------------------------------------------------
// Transport callbacks
//---------------------------------------------------------
-bool TPipe::isOpen() {
+bool TPipe::isOpen() const {
return impl_.get() != NULL;
}
diff --git a/lib/cpp/src/thrift/transport/TPipe.h b/lib/cpp/src/thrift/transport/TPipe.h
index dfc5f2c..ba149b1 100644
--- a/lib/cpp/src/thrift/transport/TPipe.h
+++ b/lib/cpp/src/thrift/transport/TPipe.h
@@ -63,16 +63,16 @@
virtual ~TPipe();
// Returns whether the pipe is open & valid.
- virtual bool isOpen();
+ bool isOpen() const override;
// Checks whether more data is available in the pipe.
- virtual bool peek();
+ bool peek() override;
// Creates and opens the named/anonymous pipe.
- virtual void open();
+ void open() override;
// Shuts down communications on the pipe.
- virtual void close();
+ void close() override;
// Reads from the pipe.
virtual uint32_t read(uint8_t* buf, uint32_t len);
@@ -95,7 +95,7 @@
HANDLE getNativeWaitHandle();
private:
- stdcxx::shared_ptr<TPipeImpl> impl_;
+ std::shared_ptr<TPipeImpl> impl_;
std::string pipename_;
diff --git a/lib/cpp/src/thrift/transport/TPipeServer.cpp b/lib/cpp/src/thrift/transport/TPipeServer.cpp
index 5923a62..47d8822 100644
--- a/lib/cpp/src/thrift/transport/TPipeServer.cpp
+++ b/lib/cpp/src/thrift/transport/TPipeServer.cpp
@@ -22,7 +22,6 @@
#include <thrift/transport/TPipe.h>
#include <thrift/transport/TPipeServer.h>
-#include <thrift/stdcxx.h>
#include <boost/noncopyable.hpp>
#ifdef _WIN32
@@ -37,14 +36,14 @@
#ifdef _WIN32
-using stdcxx::shared_ptr;
+using std::shared_ptr;
class TPipeServerImpl : boost::noncopyable {
public:
TPipeServerImpl() {}
virtual ~TPipeServerImpl() {}
virtual void interrupt() = 0;
- virtual stdcxx::shared_ptr<TTransport> acceptImpl() = 0;
+ virtual std::shared_ptr<TTransport> acceptImpl() = 0;
virtual HANDLE getPipeHandle() = 0;
virtual HANDLE getWrtPipeHandle() = 0;
@@ -75,7 +74,7 @@
virtual void interrupt() {} // not currently implemented
- virtual stdcxx::shared_ptr<TTransport> acceptImpl();
+ virtual std::shared_ptr<TTransport> acceptImpl();
virtual HANDLE getPipeHandle() { return PipeR_.h; }
virtual HANDLE getWrtPipeHandle() { return PipeW_.h; }
@@ -117,7 +116,7 @@
}
}
- virtual stdcxx::shared_ptr<TTransport> acceptImpl();
+ virtual std::shared_ptr<TTransport> acceptImpl();
virtual HANDLE getPipeHandle() { return Pipe_.h; }
virtual HANDLE getWrtPipeHandle() { return INVALID_HANDLE_VALUE; }
@@ -141,7 +140,7 @@
TCriticalSection pipe_protect_;
// only read or write these variables underneath a locked pipe_protect_
- stdcxx::shared_ptr<TPipe> cached_client_;
+ std::shared_ptr<TPipe> cached_client_;
TAutoHandle Pipe_;
};
@@ -334,8 +333,22 @@
SetEntriesInAcl(1, &ea, NULL, &acl);
PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
- InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
- SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE);
+ if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) {
+ auto lastError = GetLastError();
+ LocalFree(sd);
+ LocalFree(acl);
+ GlobalOutput.perror("TPipeServer::InitializeSecurityDescriptor() GLE=", lastError);
+ throw TTransportException(TTransportException::NOT_OPEN, "InitializeSecurityDescriptor() failed",
+ lastError);
+ }
+ if (!SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE)) {
+ auto lastError = GetLastError();
+ LocalFree(sd);
+ LocalFree(acl);
+ GlobalOutput.perror("TPipeServer::SetSecurityDescriptorDacl() GLE=", lastError);
+ throw TTransportException(TTransportException::NOT_OPEN,
+ "SetSecurityDescriptorDacl() failed", lastError);
+ }
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
@@ -354,7 +367,7 @@
0, // client time-out
&sa)); // security attributes
- DWORD lastError = GetLastError();
+ auto lastError = GetLastError();
LocalFree(sd);
LocalFree(acl);
FreeSid(everyone_sid);
@@ -365,7 +378,6 @@
throw TTransportException(TTransportException::NOT_OPEN,
"TCreateNamedPipe() failed",
lastError);
- return false;
}
Pipe_.reset(hPipe.release());
@@ -376,8 +388,17 @@
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd; // security information for pipes
- InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
- SetSecurityDescriptorDacl(&sd, true, NULL, false);
+ if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
+ {
+ GlobalOutput.perror("TPipeServer InitializeSecurityDescriptor (anon) failed, GLE=", GetLastError());
+ return false;
+ }
+ if (!SetSecurityDescriptorDacl(&sd, true, NULL, false))
+ {
+ GlobalOutput.perror("TPipeServer SetSecurityDescriptorDacl (anon) failed, GLE=",
+ GetLastError());
+ return false;
+ }
sa.lpSecurityDescriptor = &sd;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = true; // allow passing handle to child
diff --git a/lib/cpp/src/thrift/transport/TPipeServer.h b/lib/cpp/src/thrift/transport/TPipeServer.h
index 117773c..871b6af 100644
--- a/lib/cpp/src/thrift/transport/TPipeServer.h
+++ b/lib/cpp/src/thrift/transport/TPipeServer.h
@@ -20,8 +20,8 @@
#ifndef _THRIFT_TRANSPORT_TSERVERWINPIPES_H_
#define _THRIFT_TRANSPORT_TSERVERWINPIPES_H_ 1
+#include <memory>
#include <thrift/transport/TServerTransport.h>
-#include <thrift/stdcxx.h>
#ifndef _WIN32
#include <thrift/transport/TServerSocket.h>
#endif
@@ -60,9 +60,9 @@
virtual ~TPipeServer();
// Standard transport callbacks
- virtual void interrupt();
- virtual void close();
- virtual void listen();
+ void interrupt() override;
+ void close() override;
+ void listen() override;
// Accessors
std::string getPipename();
@@ -82,10 +82,10 @@
HANDLE getNativeWaitHandle();
protected:
- virtual stdcxx::shared_ptr<TTransport> acceptImpl();
+ virtual std::shared_ptr<TTransport> acceptImpl();
private:
- stdcxx::shared_ptr<TPipeServerImpl> impl_;
+ std::shared_ptr<TPipeServerImpl> impl_;
std::string pipename_;
uint32_t bufsize_;
diff --git a/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp b/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp
index 8e81ad7..b20c174 100644
--- a/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TSSLServerSocket.cpp
@@ -17,6 +17,7 @@
* under the License.
*/
+#include <thrift/thrift_export.h>
#include <thrift/transport/TSSLServerSocket.h>
#include <thrift/transport/TSSLSocket.h>
@@ -27,14 +28,14 @@
/**
* SSL server socket implementation.
*/
-TSSLServerSocket::TSSLServerSocket(int port, stdcxx::shared_ptr<TSSLSocketFactory> factory)
+TSSLServerSocket::TSSLServerSocket(int port, std::shared_ptr<TSSLSocketFactory> factory)
: TServerSocket(port), factory_(factory) {
factory_->server(true);
}
TSSLServerSocket::TSSLServerSocket(const std::string& address,
int port,
- stdcxx::shared_ptr<TSSLSocketFactory> factory)
+ std::shared_ptr<TSSLSocketFactory> factory)
: TServerSocket(address, port), factory_(factory) {
factory_->server(true);
}
@@ -42,12 +43,12 @@
TSSLServerSocket::TSSLServerSocket(int port,
int sendTimeout,
int recvTimeout,
- stdcxx::shared_ptr<TSSLSocketFactory> factory)
+ std::shared_ptr<TSSLSocketFactory> factory)
: TServerSocket(port, sendTimeout, recvTimeout), factory_(factory) {
factory_->server(true);
}
-stdcxx::shared_ptr<TSocket> TSSLServerSocket::createSocket(THRIFT_SOCKET client) {
+std::shared_ptr<TSocket> TSSLServerSocket::createSocket(THRIFT_SOCKET client) {
if (interruptableChildren_) {
return factory_->createSocket(client, pChildInterruptSockReader_);
diff --git a/lib/cpp/src/thrift/transport/TSSLServerSocket.h b/lib/cpp/src/thrift/transport/TSSLServerSocket.h
index dda9af4..44df432 100644
--- a/lib/cpp/src/thrift/transport/TSSLServerSocket.h
+++ b/lib/cpp/src/thrift/transport/TSSLServerSocket.h
@@ -20,7 +20,6 @@
#ifndef _THRIFT_TRANSPORT_TSSLSERVERSOCKET_H_
#define _THRIFT_TRANSPORT_TSSLSERVERSOCKET_H_ 1
-#include <thrift/stdcxx.h>
#include <thrift/transport/TServerSocket.h>
namespace apache {
@@ -40,7 +39,7 @@
* @param port Listening port
* @param factory SSL socket factory implementation
*/
- TSSLServerSocket(int port, stdcxx::shared_ptr<TSSLSocketFactory> factory);
+ TSSLServerSocket(int port, std::shared_ptr<TSSLSocketFactory> factory);
/**
* Constructor. Binds to the specified address.
@@ -51,7 +50,7 @@
*/
TSSLServerSocket(const std::string& address,
int port,
- stdcxx::shared_ptr<TSSLSocketFactory> factory);
+ std::shared_ptr<TSSLSocketFactory> factory);
/**
* Constructor. Binds to all interfaces.
@@ -64,11 +63,11 @@
TSSLServerSocket(int port,
int sendTimeout,
int recvTimeout,
- stdcxx::shared_ptr<TSSLSocketFactory> factory);
+ std::shared_ptr<TSSLSocketFactory> factory);
protected:
- stdcxx::shared_ptr<TSocket> createSocket(THRIFT_SOCKET socket);
- stdcxx::shared_ptr<TSSLSocketFactory> factory_;
+ std::shared_ptr<TSocket> createSocket(THRIFT_SOCKET socket) override;
+ std::shared_ptr<TSSLSocketFactory> factory_;
};
}
}
diff --git a/lib/cpp/src/thrift/transport/TSSLSocket.cpp b/lib/cpp/src/thrift/transport/TSSLSocket.cpp
index 251ef2f..b413002 100644
--- a/lib/cpp/src/thrift/transport/TSSLSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TSSLSocket.cpp
@@ -19,9 +19,10 @@
#include <thrift/thrift-config.h>
-#include <errno.h>
-#include <string>
#include <cstring>
+#include <errno.h>
+#include <memory>
+#include <string>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
@@ -95,7 +96,7 @@
}
static void dyn_lock(int mode, struct CRYPTO_dynlock_value* lock, const char*, int) {
- if (lock != NULL) {
+ if (lock != nullptr) {
if (mode & CRYPTO_LOCK) {
lock->mutex.lock();
} else {
@@ -180,7 +181,7 @@
throw TSSLException("SSL_CTX_new: Unknown protocol");
}
- if (ctx_ == NULL) {
+ if (ctx_ == nullptr) {
string errors;
buildErrors(errors);
throw TSSLException("SSL_CTX_new: " + errors);
@@ -196,15 +197,15 @@
}
SSLContext::~SSLContext() {
- if (ctx_ != NULL) {
+ if (ctx_ != nullptr) {
SSL_CTX_free(ctx_);
- ctx_ = NULL;
+ ctx_ = nullptr;
}
}
SSL* SSLContext::createSSL() {
SSL* ssl = SSL_new(ctx_);
- if (ssl == NULL) {
+ if (ssl == nullptr) {
string errors;
buildErrors(errors);
throw TSSLException("SSL_new: " + errors);
@@ -213,34 +214,34 @@
}
// TSSLSocket implementation
-TSSLSocket::TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx)
- : TSocket(), server_(false), ssl_(NULL), ctx_(ctx) {
+TSSLSocket::TSSLSocket(std::shared_ptr<SSLContext> ctx)
+ : TSocket(), server_(false), ssl_(nullptr), ctx_(ctx) {
init();
}
-TSSLSocket::TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener)
- : TSocket(), server_(false), ssl_(NULL), ctx_(ctx) {
+TSSLSocket::TSSLSocket(std::shared_ptr<SSLContext> ctx, std::shared_ptr<THRIFT_SOCKET> interruptListener)
+ : TSocket(), server_(false), ssl_(nullptr), ctx_(ctx) {
init();
interruptListener_ = interruptListener;
}
-TSSLSocket::TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx, THRIFT_SOCKET socket)
- : TSocket(socket), server_(false), ssl_(NULL), ctx_(ctx) {
+TSSLSocket::TSSLSocket(std::shared_ptr<SSLContext> ctx, THRIFT_SOCKET socket)
+ : TSocket(socket), server_(false), ssl_(nullptr), ctx_(ctx) {
init();
}
-TSSLSocket::TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx, THRIFT_SOCKET socket, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener)
- : TSocket(socket, interruptListener), server_(false), ssl_(NULL), ctx_(ctx) {
+TSSLSocket::TSSLSocket(std::shared_ptr<SSLContext> ctx, THRIFT_SOCKET socket, std::shared_ptr<THRIFT_SOCKET> interruptListener)
+ : TSocket(socket, interruptListener), server_(false), ssl_(nullptr), ctx_(ctx) {
init();
}
-TSSLSocket::TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx, string host, int port)
- : TSocket(host, port), server_(false), ssl_(NULL), ctx_(ctx) {
+TSSLSocket::TSSLSocket(std::shared_ptr<SSLContext> ctx, string host, int port)
+ : TSocket(host, port), server_(false), ssl_(nullptr), ctx_(ctx) {
init();
}
-TSSLSocket::TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx, string host, int port, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener)
- : TSocket(host, port), server_(false), ssl_(NULL), ctx_(ctx) {
+TSSLSocket::TSSLSocket(std::shared_ptr<SSLContext> ctx, string host, int port, std::shared_ptr<THRIFT_SOCKET> interruptListener)
+ : TSocket(host, port), server_(false), ssl_(nullptr), ctx_(ctx) {
init();
interruptListener_ = interruptListener;
}
@@ -266,8 +267,8 @@
eventSafe_ = false;
}
-bool TSSLSocket::isOpen() {
- if (ssl_ == NULL || !TSocket::isOpen()) {
+bool TSSLSocket::isOpen() const {
+ if (ssl_ == nullptr || !TSocket::isOpen()) {
return false;
}
int shutdown = SSL_get_shutdown(ssl_);
@@ -291,11 +292,10 @@
if (!checkHandshake())
throw TSSLException("SSL_peek: Handshake is not completed");
int rc;
- uint8_t byte;
do {
+ uint8_t byte;
rc = SSL_peek(ssl_, &byte, 1);
if (rc < 0) {
-
int errno_copy = THRIFT_GET_SOCKET_ERROR;
int error = SSL_get_error(ssl_, rc);
switch (error) {
@@ -318,6 +318,8 @@
} else if (rc == 0) {
ERR_clear_error();
break;
+ } else {
+ break;
}
} while (true);
return (rc > 0);
@@ -334,7 +336,7 @@
* Note: This method is not libevent safe.
*/
void TSSLSocket::close() {
- if (ssl_ != NULL) {
+ if (ssl_ != nullptr) {
try {
int rc;
int errno_copy = 0;
@@ -375,7 +377,7 @@
GlobalOutput.printf("SSL_shutdown: %s", te.what());
}
SSL_free(ssl_);
- ssl_ = NULL;
+ ssl_ = nullptr;
handshakeCompleted_ = false;
ERR_remove_state(0);
}
@@ -552,14 +554,14 @@
void TSSLSocket::flush() {
// Don't throw exception if not open. Thrift servers close socket twice.
- if (ssl_ == NULL) {
+ if (ssl_ == nullptr) {
return;
}
initializeHandshake();
if (!checkHandshake())
throw TSSLException("BIO_flush: Handshake is not completed");
BIO* bio = SSL_get_wbio(ssl_);
- if (bio == NULL) {
+ if (bio == nullptr) {
throw TSSLException("SSL_get_wbio returns NULL");
}
if (BIO_flush(bio) != 1) {
@@ -597,7 +599,7 @@
return;
}
- if (ssl_ == NULL) {
+ if (ssl_ == nullptr) {
initializeHandshakeParams();
}
@@ -683,19 +685,19 @@
}
X509* cert = SSL_get_peer_certificate(ssl_);
- if (cert == NULL) {
+ if (cert == nullptr) {
// certificate is not present
if (SSL_get_verify_mode(ssl_) & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
throw TSSLException("authorize: required certificate not present");
}
// certificate was optional: didn't intend to authorize remote
- if (server() && access_ != NULL) {
+ if (server() && access_ != nullptr) {
throw TSSLException("authorize: certificate required for authorization");
}
return;
}
// certificate is present
- if (access_ == NULL) {
+ if (access_ == nullptr) {
X509_free(cert);
return;
}
@@ -720,13 +722,13 @@
}
// extract subjectAlternativeName
- STACK_OF(GENERAL_NAME)* alternatives
- = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
- if (alternatives != NULL) {
+ auto* alternatives
+ = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr);
+ if (alternatives != nullptr) {
const int count = sk_GENERAL_NAME_num(alternatives);
for (int i = 0; decision == AccessManager::SKIP && i < count; i++) {
const GENERAL_NAME* name = sk_GENERAL_NAME_value(alternatives, i);
- if (name == NULL) {
+ if (name == nullptr) {
continue;
}
char* data = (char*)ASN1_STRING_data(name->d.ia5);
@@ -756,7 +758,7 @@
// extract commonName
X509_NAME* name = X509_get_subject_name(cert);
- if (name != NULL) {
+ if (name != nullptr) {
X509_NAME_ENTRY* entry;
unsigned char* utf8;
int last = -1;
@@ -765,7 +767,7 @@
if (last == -1)
break;
entry = X509_NAME_get_entry(name, last);
- if (entry == NULL)
+ if (entry == nullptr)
continue;
ASN1_STRING* common = X509_NAME_ENTRY_get_data(entry);
int size = ASN1_STRING_to_UTF8(&utf8, common);
@@ -795,7 +797,7 @@
bio = SSL_get_wbio(ssl_);
}
- if (bio == NULL) {
+ if (bio == nullptr) {
throw TSSLException("SSL_get_?bio returned NULL");
}
@@ -857,7 +859,7 @@
randomize();
}
count_++;
- ctx_ = stdcxx::shared_ptr<SSLContext>(new SSLContext(protocol));
+ ctx_ = std::make_shared<SSLContext>(protocol);
}
TSSLSocketFactory::~TSSLSocketFactory() {
@@ -869,49 +871,49 @@
}
}
-stdcxx::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket() {
- stdcxx::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_));
+std::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket() {
+ std::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_));
setup(ssl);
return ssl;
}
-stdcxx::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener) {
- stdcxx::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, interruptListener));
+std::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(std::shared_ptr<THRIFT_SOCKET> interruptListener) {
+ std::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, interruptListener));
setup(ssl);
return ssl;
}
-stdcxx::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(THRIFT_SOCKET socket) {
- stdcxx::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, socket));
+std::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(THRIFT_SOCKET socket) {
+ std::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, socket));
setup(ssl);
return ssl;
}
-stdcxx::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(THRIFT_SOCKET socket, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener) {
- stdcxx::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, socket, interruptListener));
+std::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(THRIFT_SOCKET socket, std::shared_ptr<THRIFT_SOCKET> interruptListener) {
+ std::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, socket, interruptListener));
setup(ssl);
return ssl;
}
-stdcxx::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(const string& host, int port) {
- stdcxx::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, host, port));
+std::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(const string& host, int port) {
+ std::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, host, port));
setup(ssl);
return ssl;
}
-stdcxx::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(const string& host, int port, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener) {
- stdcxx::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, host, port, interruptListener));
+std::shared_ptr<TSSLSocket> TSSLSocketFactory::createSocket(const string& host, int port, std::shared_ptr<THRIFT_SOCKET> interruptListener) {
+ std::shared_ptr<TSSLSocket> ssl(new TSSLSocket(ctx_, host, port, interruptListener));
setup(ssl);
return ssl;
}
-void TSSLSocketFactory::setup(stdcxx::shared_ptr<TSSLSocket> ssl) {
+void TSSLSocketFactory::setup(std::shared_ptr<TSSLSocket> ssl) {
ssl->server(server());
- if (access_ == NULL && !server()) {
- access_ = stdcxx::shared_ptr<AccessManager>(new DefaultClientAccessManager);
+ if (access_ == nullptr && !server()) {
+ access_ = std::shared_ptr<AccessManager>(new DefaultClientAccessManager);
}
- if (access_ != NULL) {
+ if (access_ != nullptr) {
ssl->access(access_);
}
}
@@ -935,11 +937,11 @@
} else {
mode = SSL_VERIFY_NONE;
}
- SSL_CTX_set_verify(ctx_->get(), mode, NULL);
+ SSL_CTX_set_verify(ctx_->get(), mode, nullptr);
}
void TSSLSocketFactory::loadCertificate(const char* path, const char* format) {
- if (path == NULL || format == NULL) {
+ if (path == nullptr || format == nullptr) {
throw TTransportException(TTransportException::BAD_ARGS,
"loadCertificateChain: either <path> or <format> is NULL");
}
@@ -956,7 +958,7 @@
}
void TSSLSocketFactory::loadPrivateKey(const char* path, const char* format) {
- if (path == NULL || format == NULL) {
+ if (path == nullptr || format == nullptr) {
throw TTransportException(TTransportException::BAD_ARGS,
"loadPrivateKey: either <path> or <format> is NULL");
}
@@ -971,7 +973,7 @@
}
void TSSLSocketFactory::loadTrustedCertificates(const char* path, const char* capath) {
- if (path == NULL) {
+ if (path == nullptr) {
throw TTransportException(TTransportException::BAD_ARGS,
"loadTrustedCertificates: <path> is NULL");
}
@@ -993,7 +995,7 @@
}
int TSSLSocketFactory::passwordCallback(char* password, int size, int, void* data) {
- TSSLSocketFactory* factory = (TSSLSocketFactory*)data;
+ auto* factory = (TSSLSocketFactory*)data;
string userPassword;
factory->getPassword(userPassword, size);
int length = static_cast<int>(userPassword.size());
@@ -1016,7 +1018,7 @@
errors += "; ";
}
const char* reason = ERR_reason_error_string(errorCode);
- if (reason == NULL) {
+ if (reason == nullptr) {
THRIFT_SNPRINTF(message, sizeof(message) - 1, "SSL error # %lu", errorCode);
reason = message;
}
@@ -1046,15 +1048,15 @@
/**
* Default implementation of AccessManager
*/
-Decision DefaultClientAccessManager::verify(const sockaddr_storage& sa) throw() {
+Decision DefaultClientAccessManager::verify(const sockaddr_storage& sa) noexcept {
(void)sa;
return SKIP;
}
Decision DefaultClientAccessManager::verify(const string& host,
const char* name,
- int size) throw() {
- if (host.empty() || name == NULL || size <= 0) {
+ int size) noexcept {
+ if (host.empty() || name == nullptr || size <= 0) {
return SKIP;
}
return (matchName(host.c_str(), name, size) ? ALLOW : SKIP);
@@ -1062,7 +1064,7 @@
Decision DefaultClientAccessManager::verify(const sockaddr_storage& sa,
const char* data,
- int size) throw() {
+ int size) noexcept {
bool match = false;
if (sa.ss_family == AF_INET && size == sizeof(in_addr)) {
match = (memcmp(&((sockaddr_in*)&sa)->sin_addr, data, size) == 0);
diff --git a/lib/cpp/src/thrift/transport/TSSLSocket.h b/lib/cpp/src/thrift/transport/TSSLSocket.h
index ec30cc1..87a9601 100644
--- a/lib/cpp/src/thrift/transport/TSSLSocket.h
+++ b/lib/cpp/src/thrift/transport/TSSLSocket.h
@@ -26,7 +26,6 @@
#include <openssl/ssl.h>
#include <string>
#include <thrift/concurrency/Mutex.h>
-#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@@ -70,19 +69,19 @@
*/
class TSSLSocket : public TSocket {
public:
- ~TSSLSocket();
+ ~TSSLSocket() override;
/**
* TTransport interface.
*/
- bool isOpen();
- bool peek();
- void open();
- void close();
- bool hasPendingDataToRead();
- uint32_t read(uint8_t* buf, uint32_t len);
- void write(const uint8_t* buf, uint32_t len);
- uint32_t write_partial(const uint8_t* buf, uint32_t len);
- void flush();
+ bool isOpen() const override;
+ bool peek() override;
+ void open() override;
+ void close() override;
+ bool hasPendingDataToRead() override;
+ uint32_t read(uint8_t* buf, uint32_t len) override;
+ void write(const uint8_t* buf, uint32_t len) override;
+ uint32_t write_partial(const uint8_t* buf, uint32_t len) override;
+ void flush() override;
/**
* Set whether to use client or server side SSL handshake protocol.
*
@@ -98,7 +97,7 @@
*
* @param manager Instance of AccessManager
*/
- virtual void access(stdcxx::shared_ptr<AccessManager> manager) { access_ = manager; }
+ virtual void access(std::shared_ptr<AccessManager> manager) { access_ = manager; }
/**
* Set eventSafe flag if libevent is used.
*/
@@ -112,37 +111,37 @@
/**
* Constructor.
*/
- TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx);
+ TSSLSocket(std::shared_ptr<SSLContext> ctx);
/**
* Constructor with an interrupt signal.
*/
- TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener);
+ TSSLSocket(std::shared_ptr<SSLContext> ctx, std::shared_ptr<THRIFT_SOCKET> interruptListener);
/**
* Constructor, create an instance of TSSLSocket given an existing socket.
*
* @param socket An existing socket
*/
- TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx, THRIFT_SOCKET socket);
+ TSSLSocket(std::shared_ptr<SSLContext> ctx, THRIFT_SOCKET socket);
/**
* Constructor, create an instance of TSSLSocket given an existing socket that can be interrupted.
*
* @param socket An existing socket
*/
- TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx, THRIFT_SOCKET socket, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener);
+ TSSLSocket(std::shared_ptr<SSLContext> ctx, THRIFT_SOCKET socket, std::shared_ptr<THRIFT_SOCKET> interruptListener);
/**
* Constructor.
*
* @param host Remote host name
* @param port Remote port number
*/
- TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx, std::string host, int port);
+ TSSLSocket(std::shared_ptr<SSLContext> ctx, std::string host, int port);
/**
* Constructor with an interrupt signal.
*
* @param host Remote host name
* @param port Remote port number
*/
- TSSLSocket(stdcxx::shared_ptr<SSLContext> ctx, std::string host, int port, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener);
+ TSSLSocket(std::shared_ptr<SSLContext> ctx, std::string host, int port, std::shared_ptr<THRIFT_SOCKET> interruptListener);
/**
* Authorize peer access after SSL handshake completes.
*/
@@ -171,8 +170,8 @@
bool server_;
SSL* ssl_;
- stdcxx::shared_ptr<SSLContext> ctx_;
- stdcxx::shared_ptr<AccessManager> access_;
+ std::shared_ptr<SSLContext> ctx_;
+ std::shared_ptr<AccessManager> access_;
friend class TSSLSocketFactory;
private:
@@ -212,37 +211,37 @@
/**
* Create an instance of TSSLSocket with a fresh new socket.
*/
- virtual stdcxx::shared_ptr<TSSLSocket> createSocket();
+ virtual std::shared_ptr<TSSLSocket> createSocket();
/**
* Create an instance of TSSLSocket with a fresh new socket, which is interruptable.
*/
- virtual stdcxx::shared_ptr<TSSLSocket> createSocket(stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener);
+ virtual std::shared_ptr<TSSLSocket> createSocket(std::shared_ptr<THRIFT_SOCKET> interruptListener);
/**
* Create an instance of TSSLSocket with the given socket.
*
* @param socket An existing socket.
*/
- virtual stdcxx::shared_ptr<TSSLSocket> createSocket(THRIFT_SOCKET socket);
+ virtual std::shared_ptr<TSSLSocket> createSocket(THRIFT_SOCKET socket);
/**
* Create an instance of TSSLSocket with the given socket which is interruptable.
*
* @param socket An existing socket.
*/
- virtual stdcxx::shared_ptr<TSSLSocket> createSocket(THRIFT_SOCKET socket, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener);
+ virtual std::shared_ptr<TSSLSocket> createSocket(THRIFT_SOCKET socket, std::shared_ptr<THRIFT_SOCKET> interruptListener);
/**
* Create an instance of TSSLSocket.
*
* @param host Remote host to be connected to
* @param port Remote port to be connected to
*/
- virtual stdcxx::shared_ptr<TSSLSocket> createSocket(const std::string& host, int port);
+ virtual std::shared_ptr<TSSLSocket> createSocket(const std::string& host, int port);
/**
* Create an instance of TSSLSocket.
*
* @param host Remote host to be connected to
* @param port Remote port to be connected to
*/
- virtual stdcxx::shared_ptr<TSSLSocket> createSocket(const std::string& host, int port, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener);
+ virtual std::shared_ptr<TSSLSocket> createSocket(const std::string& host, int port, std::shared_ptr<THRIFT_SOCKET> interruptListener);
/**
* Set ciphers to be used in SSL handshake process.
*
@@ -274,7 +273,7 @@
*
* @param path Path to trusted certificate file
*/
- virtual void loadTrustedCertificates(const char* path, const char* capath = NULL);
+ virtual void loadTrustedCertificates(const char* path, const char* capath = nullptr);
/**
* Default randomize method.
*/
@@ -300,13 +299,13 @@
*
* @param manager The AccessManager instance
*/
- virtual void access(stdcxx::shared_ptr<AccessManager> manager) { access_ = manager; }
+ virtual void access(std::shared_ptr<AccessManager> manager) { access_ = manager; }
static void setManualOpenSSLInitialization(bool manualOpenSSLInitialization) {
manualOpenSSLInitialization_ = manualOpenSSLInitialization;
}
protected:
- stdcxx::shared_ptr<SSLContext> ctx_;
+ std::shared_ptr<SSLContext> ctx_;
/**
* Override this method for custom password callback. It may be called
@@ -319,11 +318,11 @@
private:
bool server_;
- stdcxx::shared_ptr<AccessManager> access_;
+ std::shared_ptr<AccessManager> access_;
static concurrency::Mutex mutex_;
static uint64_t count_;
- static bool manualOpenSSLInitialization_;
- void setup(stdcxx::shared_ptr<TSSLSocket> ssl);
+ THRIFT_EXPORT static bool manualOpenSSLInitialization_;
+ void setup(std::shared_ptr<TSSLSocket> ssl);
static int passwordCallback(char* password, int size, int, void* data);
};
@@ -335,7 +334,7 @@
TSSLException(const std::string& message)
: TTransportException(TTransportException::INTERNAL_ERROR, message) {}
- virtual const char* what() const throw() {
+ const char* what() const noexcept override {
if (message_.empty()) {
return "TSSLException";
} else {
@@ -374,7 +373,7 @@
/**
* Destructor
*/
- virtual ~AccessManager() {}
+ virtual ~AccessManager() = default;
/**
* Determine whether the peer should be granted access or not. It's called
* once after the SSL handshake completes successfully, before peer certificate
@@ -386,7 +385,7 @@
* @param sa Peer IP address
* @return True if the peer is trusted, false otherwise
*/
- virtual Decision verify(const sockaddr_storage& /* sa */) throw() { return DENY; }
+ virtual Decision verify(const sockaddr_storage& /* sa */) noexcept { return DENY; }
/**
* Determine whether the peer should be granted access or not. It's called
* every time a DNS subjectAltName/common name is extracted from peer's
@@ -402,7 +401,7 @@
*/
virtual Decision verify(const std::string& /* host */,
const char* /* name */,
- int /* size */) throw() {
+ int /* size */) noexcept {
return DENY;
}
/**
@@ -416,7 +415,7 @@
*/
virtual Decision verify(const sockaddr_storage& /* sa */,
const char* /* data */,
- int /* size */) throw() {
+ int /* size */) noexcept {
return DENY;
}
};
@@ -426,9 +425,9 @@
class DefaultClientAccessManager : public AccessManager {
public:
// AccessManager interface
- Decision verify(const sockaddr_storage& sa) throw();
- Decision verify(const std::string& host, const char* name, int size) throw();
- Decision verify(const sockaddr_storage& sa, const char* data, int size) throw();
+ Decision verify(const sockaddr_storage& sa) noexcept override;
+ Decision verify(const std::string& host, const char* name, int size) noexcept override;
+ Decision verify(const sockaddr_storage& sa, const char* data, int size) noexcept override;
};
}
}
diff --git a/lib/cpp/src/thrift/transport/TServerSocket.cpp b/lib/cpp/src/thrift/transport/TServerSocket.cpp
index 3f11a59..ece0544 100644
--- a/lib/cpp/src/thrift/transport/TServerSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TServerSocket.cpp
@@ -20,6 +20,7 @@
#include <thrift/thrift-config.h>
#include <cstring>
+#include <memory>
#include <stdexcept>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
@@ -46,7 +47,6 @@
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/PlatformSocket.h>
-#include <thrift/stdcxx.h>
#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
@@ -81,20 +81,20 @@
namespace thrift {
namespace transport {
-using stdcxx::shared_ptr;
+using std::shared_ptr;
TGetAddrInfoWrapper::TGetAddrInfoWrapper(const char* node,
const char* service,
const struct addrinfo* hints)
- : node_(node), service_(service), hints_(hints), res_(NULL) {}
+ : node_(node), service_(service), hints_(hints), res_(nullptr) {}
TGetAddrInfoWrapper::~TGetAddrInfoWrapper() {
- if (this->res_ != NULL)
+ if (this->res_ != nullptr)
freeaddrinfo(this->res_);
}
int TGetAddrInfoWrapper::init() {
- if (this->res_ == NULL)
+ if (this->res_ == nullptr)
return getaddrinfo(this->node_, this->service_, this->hints_, &(this->res_));
return 0;
}
@@ -249,7 +249,7 @@
} else {
childInterruptSockWriter_ = sv[1];
pChildInterruptSockReader_
- = stdcxx::shared_ptr<THRIFT_SOCKET>(new THRIFT_SOCKET(sv[0]), destroyer_of_fine_sockets);
+ = std::shared_ptr<THRIFT_SOCKET>(new THRIFT_SOCKET(sv[0]), destroyer_of_fine_sockets);
}
// Validate port number
@@ -269,7 +269,7 @@
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
// If address is not specified use wildcard address (NULL)
- TGetAddrInfoWrapper info(address_.empty() ? NULL : &address_[0], port, &hints);
+ TGetAddrInfoWrapper info(address_.empty() ? nullptr : &address_[0], port, &hints);
error = info.init();
if (error) {
@@ -282,13 +282,13 @@
// Pick the ipv6 address first since ipv4 addresses can be mapped
// into ipv6 space.
for (res = info.res(); res; res = res->ai_next) {
- if (res->ai_family == AF_INET6 || res->ai_next == NULL)
+ if (res->ai_family == AF_INET6 || res->ai_next == nullptr)
break;
}
if (!path_.empty()) {
serverSocket_ = socket(PF_UNIX, SOCK_STREAM, IPPROTO_IP);
- } else if (res != NULL) {
+ } else if (res != nullptr) {
serverSocket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
}
@@ -435,7 +435,7 @@
// Unix Domain Socket
size_t len = path_.size() + 1;
- if (len > sizeof(((sockaddr_un*)NULL)->sun_path)) {
+ if (len > sizeof(((sockaddr_un*)nullptr)->sun_path)) {
errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TSocket::listen() Unix Domain socket path too long", errno_copy);
throw TTransportException(TTransportException::NOT_OPEN,
@@ -447,7 +447,7 @@
address.sun_family = AF_UNIX;
memcpy(address.sun_path, path_.c_str(), len);
- socklen_t structlen = static_cast<socklen_t>(sizeof(address));
+ auto structlen = static_cast<socklen_t>(sizeof(address));
if (!address.sun_path[0]) { // abstract namespace socket
#ifdef __linux__
@@ -491,10 +491,10 @@
GlobalOutput.perror("TServerSocket::getPort() getsockname() ", errno_copy);
} else {
if (sa.ss_family == AF_INET6) {
- const struct sockaddr_in6* sin = reinterpret_cast<const struct sockaddr_in6*>(&sa);
+ const auto* sin = reinterpret_cast<const struct sockaddr_in6*>(&sa);
port_ = ntohs(sin->sin6_port);
} else {
- const struct sockaddr_in* sin = reinterpret_cast<const struct sockaddr_in*>(&sa);
+ const auto* sin = reinterpret_cast<const struct sockaddr_in*>(&sa);
port_ = ntohs(sin->sin_port);
}
}
@@ -642,9 +642,9 @@
shared_ptr<TSocket> TServerSocket::createSocket(THRIFT_SOCKET clientSocket) {
if (interruptableChildren_) {
- return shared_ptr<TSocket>(new TSocket(clientSocket, pChildInterruptSockReader_));
+ return std::make_shared<TSocket>(clientSocket, pChildInterruptSockReader_);
} else {
- return shared_ptr<TSocket>(new TSocket(clientSocket));
+ return std::make_shared<TSocket>(clientSocket);
}
}
diff --git a/lib/cpp/src/thrift/transport/TServerSocket.h b/lib/cpp/src/thrift/transport/TServerSocket.h
index 1daaa82..d640968 100644
--- a/lib/cpp/src/thrift/transport/TServerSocket.h
+++ b/lib/cpp/src/thrift/transport/TServerSocket.h
@@ -21,7 +21,6 @@
#define _THRIFT_TRANSPORT_TSERVERSOCKET_H_ 1
#include <thrift/concurrency/Mutex.h>
-#include <thrift/stdcxx.h>
#include <thrift/transport/PlatformSocket.h>
#include <thrift/transport/TServerTransport.h>
@@ -62,7 +61,7 @@
*/
class TServerSocket : public TServerTransport {
public:
- typedef apache::thrift::stdcxx::function<void(THRIFT_SOCKET fd)> socket_func_t;
+ typedef std::function<void(THRIFT_SOCKET fd)> socket_func_t;
const static int DEFAULT_BACKLOG = 1024;
@@ -97,7 +96,7 @@
*/
TServerSocket(const std::string& path);
- virtual ~TServerSocket();
+ ~TServerSocket() override;
void setSendTimeout(int sendTimeout);
void setRecvTimeout(int recvTimeout);
@@ -137,20 +136,20 @@
// \throws std::logic_error if listen() has been called
void setInterruptableChildren(bool enable);
- THRIFT_SOCKET getSocketFD() { return serverSocket_; }
+ THRIFT_SOCKET getSocketFD() override { return serverSocket_; }
int getPort();
- void listen();
- void interrupt();
- void interruptChildren();
- void close();
+ void listen() override;
+ void interrupt() override;
+ void interruptChildren() override;
+ void close() override;
protected:
- stdcxx::shared_ptr<TTransport> acceptImpl();
- virtual stdcxx::shared_ptr<TSocket> createSocket(THRIFT_SOCKET client);
+ std::shared_ptr<TTransport> acceptImpl() override;
+ virtual std::shared_ptr<TSocket> createSocket(THRIFT_SOCKET client);
bool interruptableChildren_;
- stdcxx::shared_ptr<THRIFT_SOCKET> pChildInterruptSockReader_; // if interruptableChildren_ this is shared with child TSockets
+ std::shared_ptr<THRIFT_SOCKET> pChildInterruptSockReader_; // if interruptableChildren_ this is shared with child TSockets
private:
void notify(THRIFT_SOCKET notifySock);
diff --git a/lib/cpp/src/thrift/transport/TServerTransport.h b/lib/cpp/src/thrift/transport/TServerTransport.h
index 9d5a3d5..f465bb3 100644
--- a/lib/cpp/src/thrift/transport/TServerTransport.h
+++ b/lib/cpp/src/thrift/transport/TServerTransport.h
@@ -22,7 +22,6 @@
#include <thrift/transport/TTransport.h>
#include <thrift/transport/TTransportException.h>
-#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@@ -36,7 +35,7 @@
*/
class TServerTransport {
public:
- virtual ~TServerTransport() {}
+ virtual ~TServerTransport() = default;
/**
* Starts the server transport listening for new connections. Prior to this
@@ -56,8 +55,8 @@
* @return A new TTransport object
* @throws TTransportException if there is an error
*/
- stdcxx::shared_ptr<TTransport> accept() {
- stdcxx::shared_ptr<TTransport> result = acceptImpl();
+ std::shared_ptr<TTransport> accept() {
+ std::shared_ptr<TTransport> result = acceptImpl();
if (!result) {
throw TTransportException("accept() may not return NULL");
}
@@ -97,7 +96,7 @@
virtual void close() = 0;
protected:
- TServerTransport() {}
+ TServerTransport() = default;
/**
* Subclasses should implement this function for accept.
@@ -105,7 +104,7 @@
* @return A newly allocated TTransport object
* @throw TTransportException If an error occurs
*/
- virtual stdcxx::shared_ptr<TTransport> acceptImpl() = 0;
+ virtual std::shared_ptr<TTransport> acceptImpl() = 0;
};
}
}
diff --git a/lib/cpp/src/thrift/transport/TShortReadTransport.h b/lib/cpp/src/thrift/transport/TShortReadTransport.h
index 550b6ba..185c78d 100644
--- a/lib/cpp/src/thrift/transport/TShortReadTransport.h
+++ b/lib/cpp/src/thrift/transport/TShortReadTransport.h
@@ -38,16 +38,16 @@
*/
class TShortReadTransport : public TVirtualTransport<TShortReadTransport> {
public:
- TShortReadTransport(stdcxx::shared_ptr<TTransport> transport, double full_prob)
+ TShortReadTransport(std::shared_ptr<TTransport> transport, double full_prob)
: transport_(transport), fullProb_(full_prob) {}
- bool isOpen() { return transport_->isOpen(); }
+ bool isOpen() const override { return transport_->isOpen(); }
- bool peek() { return transport_->peek(); }
+ bool peek() override { return transport_->peek(); }
- void open() { transport_->open(); }
+ void open() override { transport_->open(); }
- void close() { transport_->close(); }
+ void close() override { transport_->close(); }
uint32_t read(uint8_t* buf, uint32_t len) {
if (len == 0) {
@@ -62,16 +62,16 @@
void write(const uint8_t* buf, uint32_t len) { transport_->write(buf, len); }
- void flush() { transport_->flush(); }
+ void flush() override { transport_->flush(); }
const uint8_t* borrow(uint8_t* buf, uint32_t* len) { return transport_->borrow(buf, len); }
void consume(uint32_t len) { return transport_->consume(len); }
- stdcxx::shared_ptr<TTransport> getUnderlyingTransport() { return transport_; }
+ std::shared_ptr<TTransport> getUnderlyingTransport() { return transport_; }
protected:
- stdcxx::shared_ptr<TTransport> transport_;
+ std::shared_ptr<TTransport> transport_;
double fullProb_;
};
}
diff --git a/lib/cpp/src/thrift/transport/TSocket.cpp b/lib/cpp/src/thrift/transport/TSocket.cpp
index 18cadbc..977834d 100644
--- a/lib/cpp/src/thrift/transport/TSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TSocket.cpp
@@ -144,7 +144,7 @@
#endif
}
-TSocket::TSocket(THRIFT_SOCKET socket, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener)
+TSocket::TSocket(THRIFT_SOCKET socket, std::shared_ptr<THRIFT_SOCKET> interruptListener)
: port_(0),
socket_(socket),
peerPort_(0),
@@ -190,7 +190,7 @@
return numBytesAvailable > 0;
}
-bool TSocket::isOpen() {
+bool TSocket::isOpen() const {
return (socket_ != THRIFT_INVALID_SOCKET);
}
@@ -324,7 +324,7 @@
#ifndef _WIN32
size_t len = path_.size() + 1;
- if (len > sizeof(((sockaddr_un*)NULL)->sun_path)) {
+ if (len > sizeof(((sockaddr_un*)nullptr)->sun_path)) {
int errno_copy = THRIFT_GET_SOCKET_ERROR;
GlobalOutput.perror("TSocket::open() Unix Domain socket path too long", errno_copy);
throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path too long");
@@ -334,7 +334,7 @@
address.sun_family = AF_UNIX;
memcpy(address.sun_path, path_.c_str(), len);
- socklen_t structlen = static_cast<socklen_t>(sizeof(address));
+ auto structlen = static_cast<socklen_t>(sizeof(address));
if (!address.sun_path[0]) { // abstract namespace socket
#ifdef __linux__
@@ -433,7 +433,7 @@
void TSocket::unix_open() {
if (!path_.empty()) {
// Unix Domain SOcket does not need addrinfo struct, so we pass NULL
- openConnection(NULL);
+ openConnection(nullptr);
}
}
@@ -453,8 +453,8 @@
}
struct addrinfo hints, *res, *res0;
- res = NULL;
- res0 = NULL;
+ res = nullptr;
+ res0 = nullptr;
int error;
char port[sizeof("65535")];
std::memset(&hints, 0, sizeof(hints));
@@ -540,7 +540,7 @@
// Read from the socket
struct timeval begin;
if (recvTimeout_ > 0) {
- THRIFT_GETTIMEOFDAY(&begin, NULL);
+ THRIFT_GETTIMEOFDAY(&begin, nullptr);
} else {
// if there is no read timeout we don't need the TOD to determine whether
// an THRIFT_EAGAIN is due to a timeout or an out-of-resource condition.
@@ -592,8 +592,8 @@
}
// check if this is the lack of resources or timeout case
struct timeval end;
- THRIFT_GETTIMEOFDAY(&end, NULL);
- uint32_t readElapsedMicros = static_cast<uint32_t>(((end.tv_sec - begin.tv_sec) * 1000 * 1000)
+ THRIFT_GETTIMEOFDAY(&end, nullptr);
+ auto readElapsedMicros = static_cast<uint32_t>(((end.tv_sec - begin.tv_sec) * 1000 * 1000)
+ (end.tv_usec - begin.tv_usec));
if (!eagainThresholdMicros || (readElapsedMicros < eagainThresholdMicros)) {
@@ -807,7 +807,7 @@
maxRecvRetries_ = maxRecvRetries;
}
-string TSocket::getSocketInfo() {
+string TSocket::getSocketInfo() const {
std::ostringstream oss;
if (path_.empty()) {
if (host_.empty() || port_ == 0) {
@@ -822,7 +822,7 @@
return oss.str();
}
-std::string TSocket::getPeerHost() {
+std::string TSocket::getPeerHost() const {
if (peerHost_.empty() && path_.empty()) {
struct sockaddr_storage addr;
struct sockaddr* addrPtr;
@@ -834,14 +834,14 @@
addrPtr = getCachedAddress(&addrLen);
- if (addrPtr == NULL) {
+ if (addrPtr == nullptr) {
addrLen = sizeof(addr);
if (getpeername(socket_, (sockaddr*)&addr, &addrLen) != 0) {
return peerHost_;
}
addrPtr = (sockaddr*)&addr;
- setCachedAddress(addrPtr, addrLen);
+ const_cast<TSocket&>(*this).setCachedAddress(addrPtr, addrLen);
}
char clienthost[NI_MAXHOST];
@@ -860,7 +860,7 @@
return peerHost_;
}
-std::string TSocket::getPeerAddress() {
+std::string TSocket::getPeerAddress() const {
if (peerAddress_.empty() && path_.empty()) {
struct sockaddr_storage addr;
struct sockaddr* addrPtr;
@@ -872,14 +872,14 @@
addrPtr = getCachedAddress(&addrLen);
- if (addrPtr == NULL) {
+ if (addrPtr == nullptr) {
addrLen = sizeof(addr);
if (getpeername(socket_, (sockaddr*)&addr, &addrLen) != 0) {
return peerAddress_;
}
addrPtr = (sockaddr*)&addr;
- setCachedAddress(addrPtr, addrLen);
+ const_cast<TSocket&>(*this).setCachedAddress(addrPtr, addrLen);
}
char clienthost[NI_MAXHOST];
@@ -899,7 +899,7 @@
return peerAddress_;
}
-int TSocket::getPeerPort() {
+int TSocket::getPeerPort() const {
getPeerAddress();
return peerPort_;
}
@@ -937,7 +937,7 @@
return (sockaddr*)&cachedPeerAddr_.ipv6;
default:
- return NULL;
+ return nullptr;
}
}
@@ -949,7 +949,7 @@
return useLowMinRto_;
}
-const std::string TSocket::getOrigin() {
+const std::string TSocket::getOrigin() const {
std::ostringstream oss;
oss << getPeerHost() << ":" << getPeerPort();
return oss.str();
diff --git a/lib/cpp/src/thrift/transport/TSocket.h b/lib/cpp/src/thrift/transport/TSocket.h
index 66d9e6c..b0e8ade 100644
--- a/lib/cpp/src/thrift/transport/TSocket.h
+++ b/lib/cpp/src/thrift/transport/TSocket.h
@@ -74,33 +74,33 @@
/**
* Destroyes the socket object, closing it if necessary.
*/
- virtual ~TSocket();
+ ~TSocket() override;
/**
* Whether the socket is alive.
*
* @return Is the socket alive?
*/
- virtual bool isOpen();
+ bool isOpen() const override;
/**
* Checks whether there is more data available in the socket to read.
*
* This call blocks until at least one byte is available or the socket is closed.
*/
- virtual bool peek();
+ bool peek() override;
/**
* Creates and opens the UNIX socket.
*
* @throws TTransportException If the socket could not connect
*/
- virtual void open();
+ void open() override;
/**
* Shuts down communications on the socket.
*/
- virtual void close();
+ void close() override;
/**
* Determines whether there is pending data to read or not.
@@ -208,22 +208,22 @@
/**
* Get socket information formatted as a string <Host: x Port: x>
*/
- std::string getSocketInfo();
+ std::string getSocketInfo() const;
/**
* Returns the DNS name of the host to which the socket is connected
*/
- std::string getPeerHost();
+ std::string getPeerHost() const;
/**
* Returns the address of the host to which the socket is connected
*/
- std::string getPeerAddress();
+ std::string getPeerAddress() const;
/**
* Returns the port of the host to which the socket is connected
**/
- int getPeerPort();
+ int getPeerPort() const;
/**
* Returns the underlying socket file descriptor.
@@ -259,7 +259,7 @@
*
* @return string peer host identifier and port
*/
- virtual const std::string getOrigin();
+ const std::string getOrigin() const override;
/**
* Constructor to create socket from file descriptor.
@@ -270,7 +270,7 @@
* Constructor to create socket from file descriptor that
* can be interrupted safely.
*/
- TSocket(THRIFT_SOCKET socket, stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener);
+ TSocket(THRIFT_SOCKET socket, std::shared_ptr<THRIFT_SOCKET> interruptListener);
/**
* Set a cache of the peer address (used when trivially available: e.g.
@@ -295,19 +295,19 @@
THRIFT_SOCKET socket_;
/** Peer hostname */
- std::string peerHost_;
+ mutable std::string peerHost_;
/** Peer address */
- std::string peerAddress_;
+ mutable std::string peerAddress_;
/** Peer port */
- int peerPort_;
+ mutable int peerPort_;
/**
* A shared socket pointer that will interrupt a blocking read if data
* becomes available on it
*/
- stdcxx::shared_ptr<THRIFT_SOCKET> interruptListener_;
+ std::shared_ptr<THRIFT_SOCKET> interruptListener_;
/** Connect timeout in ms */
int connTimeout_;
diff --git a/lib/cpp/src/thrift/transport/TSocketPool.cpp b/lib/cpp/src/thrift/transport/TSocketPool.cpp
index a34d135..b6e79d3 100644
--- a/lib/cpp/src/thrift/transport/TSocketPool.cpp
+++ b/lib/cpp/src/thrift/transport/TSocketPool.cpp
@@ -21,6 +21,7 @@
#include <algorithm>
#include <iostream>
+#include <memory>
#if __cplusplus >= 201703L
#include <random>
#endif
@@ -35,7 +36,7 @@
namespace thrift {
namespace transport {
-using stdcxx::shared_ptr;
+using std::shared_ptr;
/**
* TSocketPoolServer implementation
@@ -94,8 +95,8 @@
maxConsecutiveFailures_(1),
randomize_(true),
alwaysTryLast_(true) {
- for (unsigned i = 0; i < servers.size(); ++i) {
- addServer(servers[i].first, servers[i].second);
+ for (const auto & server : servers) {
+ addServer(server.first, server.second);
}
}
@@ -129,7 +130,7 @@
}
void TSocketPool::addServer(const string& host, int port) {
- servers_.push_back(shared_ptr<TSocketPoolServer>(new TSocketPoolServer(host, port)));
+ servers_.push_back(std::make_shared<TSocketPoolServer>(host, port));
}
void TSocketPool::addServer(shared_ptr<TSocketPoolServer>& server) {
@@ -216,7 +217,7 @@
if (server->lastFailTime_ > 0) {
// The server was marked as down, so check if enough time has elapsed to retry
- time_t elapsedTime = time(NULL) - server->lastFailTime_;
+ time_t elapsedTime = time(nullptr) - server->lastFailTime_;
if (elapsedTime > retryInterval_) {
retryIntervalPassed = true;
}
@@ -245,7 +246,7 @@
if (server->consecutiveFailures_ > maxConsecutiveFailures_) {
// Mark server as down
server->consecutiveFailures_ = 0;
- server->lastFailTime_ = time(NULL);
+ server->lastFailTime_ = time(nullptr);
}
}
}
diff --git a/lib/cpp/src/thrift/transport/TSocketPool.h b/lib/cpp/src/thrift/transport/TSocketPool.h
index bd49e55..97a2b90 100644
--- a/lib/cpp/src/thrift/transport/TSocketPool.h
+++ b/lib/cpp/src/thrift/transport/TSocketPool.h
@@ -92,7 +92,7 @@
*
* @param servers list of TSocketPoolServers
*/
- TSocketPool(const std::vector<stdcxx::shared_ptr<TSocketPoolServer> >& servers);
+ TSocketPool(const std::vector<std::shared_ptr<TSocketPoolServer> >& servers);
/**
* Socket pool constructor
@@ -105,7 +105,7 @@
/**
* Destroyes the socket object, closing it if necessary.
*/
- virtual ~TSocketPool();
+ ~TSocketPool() override;
/**
* Add a server to the pool
@@ -115,17 +115,17 @@
/**
* Add a server to the pool
*/
- void addServer(stdcxx::shared_ptr<TSocketPoolServer>& server);
+ void addServer(std::shared_ptr<TSocketPoolServer>& server);
/**
* Set list of servers in this pool
*/
- void setServers(const std::vector<stdcxx::shared_ptr<TSocketPoolServer> >& servers);
+ void setServers(const std::vector<std::shared_ptr<TSocketPoolServer> >& servers);
/**
* Get list of servers in this pool
*/
- void getServers(std::vector<stdcxx::shared_ptr<TSocketPoolServer> >& servers);
+ void getServers(std::vector<std::shared_ptr<TSocketPoolServer> >& servers);
/**
* Sets how many times to keep retrying a host in the connect function.
@@ -155,21 +155,21 @@
/**
* Creates and opens the UNIX socket.
*/
- void open();
+ void open() override;
/*
* Closes the UNIX socket
*/
- void close();
+ void close() override;
protected:
- void setCurrentServer(const stdcxx::shared_ptr<TSocketPoolServer>& server);
+ void setCurrentServer(const std::shared_ptr<TSocketPoolServer>& server);
/** List of servers to connect to */
- std::vector<stdcxx::shared_ptr<TSocketPoolServer> > servers_;
+ std::vector<std::shared_ptr<TSocketPoolServer> > servers_;
/** Current server */
- stdcxx::shared_ptr<TSocketPoolServer> currentServer_;
+ std::shared_ptr<TSocketPoolServer> currentServer_;
/** How many times to retry each host in connect */
int numRetries_;
diff --git a/lib/cpp/src/thrift/transport/TTransport.h b/lib/cpp/src/thrift/transport/TTransport.h
index de03290..891bfe1 100644
--- a/lib/cpp/src/thrift/transport/TTransport.h
+++ b/lib/cpp/src/thrift/transport/TTransport.h
@@ -21,8 +21,8 @@
#define _THRIFT_TRANSPORT_TTRANSPORT_H_ 1
#include <thrift/Thrift.h>
-#include <thrift/stdcxx.h>
#include <thrift/transport/TTransportException.h>
+#include <memory>
#include <string>
namespace apache {
@@ -58,12 +58,12 @@
/**
* Virtual deconstructor.
*/
- virtual ~TTransport() {}
+ virtual ~TTransport() = default;
/**
* Whether this transport is open.
*/
- virtual bool isOpen() { return false; }
+ virtual bool isOpen() const { return false; }
/**
* Tests whether there is more data to read or if the remote side is
@@ -209,7 +209,7 @@
T_VIRTUAL_CALL();
return borrow_virt(buf, len);
}
- virtual const uint8_t* borrow_virt(uint8_t* /* buf */, uint32_t* /* len */) { return NULL; }
+ virtual const uint8_t* borrow_virt(uint8_t* /* buf */, uint32_t* /* len */) { return nullptr; }
/**
* Remove len bytes from the transport. This should always follow a borrow
@@ -236,13 +236,13 @@
*
* The returned value can be used in a log message for example
*/
- virtual const std::string getOrigin() { return "Unknown"; }
+ virtual const std::string getOrigin() const { return "Unknown"; }
protected:
/**
* Simple constructor.
*/
- TTransport() {}
+ TTransport() = default;
};
/**
@@ -253,14 +253,14 @@
*/
class TTransportFactory {
public:
- TTransportFactory() {}
+ TTransportFactory() = default;
- virtual ~TTransportFactory() {}
+ virtual ~TTransportFactory() = default;
/**
* Default implementation does nothing, just returns the transport given.
*/
- virtual stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> trans) {
+ virtual std::shared_ptr<TTransport> getTransport(std::shared_ptr<TTransport> trans) {
return trans;
}
};
diff --git a/lib/cpp/src/thrift/transport/TTransportException.cpp b/lib/cpp/src/thrift/transport/TTransportException.cpp
index 9e15dbd..a527317 100644
--- a/lib/cpp/src/thrift/transport/TTransportException.cpp
+++ b/lib/cpp/src/thrift/transport/TTransportException.cpp
@@ -28,7 +28,7 @@
namespace thrift {
namespace transport {
-const char* TTransportException::what() const throw() {
+const char* TTransportException::what() const noexcept {
if (message_.empty()) {
switch (type_) {
case UNKNOWN:
diff --git a/lib/cpp/src/thrift/transport/TTransportException.h b/lib/cpp/src/thrift/transport/TTransportException.h
index dbbb971..38b7521 100644
--- a/lib/cpp/src/thrift/transport/TTransportException.h
+++ b/lib/cpp/src/thrift/transport/TTransportException.h
@@ -65,7 +65,7 @@
TTransportException(TTransportExceptionType type, const std::string& message, int errno_copy)
: apache::thrift::TException(message + ": " + TOutput::strerror_s(errno_copy)), type_(type) {}
- virtual ~TTransportException() throw() {}
+ ~TTransportException() noexcept override = default;
/**
* Returns an error code that provides information about the type of error
@@ -73,9 +73,9 @@
*
* @return Error code
*/
- TTransportExceptionType getType() const throw() { return type_; }
+ TTransportExceptionType getType() const noexcept { return type_; }
- virtual const char* what() const throw();
+ const char* what() const noexcept override;
protected:
/** Just like strerror_r but returns a C++ string object. */
diff --git a/lib/cpp/src/thrift/transport/TTransportUtils.cpp b/lib/cpp/src/thrift/transport/TTransportUtils.cpp
index 5a236dc..69372f3 100644
--- a/lib/cpp/src/thrift/transport/TTransportUtils.cpp
+++ b/lib/cpp/src/thrift/transport/TTransportUtils.cpp
@@ -41,8 +41,8 @@
// Double the size of the underlying buffer if it is full
if (rLen_ == rBufSize_) {
rBufSize_ *= 2;
- uint8_t *tmpBuf = (uint8_t*)std::realloc(rBuf_, sizeof(uint8_t) * rBufSize_);
- if (tmpBuf == NULL) {
+ auto *tmpBuf = (uint8_t*)std::realloc(rBuf_, sizeof(uint8_t) * rBufSize_);
+ if (tmpBuf == nullptr) {
throw std::bad_alloc();
}
rBuf_ = tmpBuf;
@@ -77,8 +77,8 @@
while ((len + wLen_) >= newBufSize) {
newBufSize *= 2;
}
- uint8_t *tmpBuf= (uint8_t*)std::realloc(wBuf_, sizeof(uint8_t) * newBufSize);
- if (tmpBuf == NULL) {
+ auto *tmpBuf= (uint8_t*)std::realloc(wBuf_, sizeof(uint8_t) * newBufSize);
+ if (tmpBuf == nullptr) {
throw std::bad_alloc();
}
wBuf_ = tmpBuf;
@@ -103,15 +103,14 @@
}
TPipedFileReaderTransport::TPipedFileReaderTransport(
- stdcxx::shared_ptr<TFileReaderTransport> srcTrans,
- stdcxx::shared_ptr<TTransport> dstTrans)
+ std::shared_ptr<TFileReaderTransport> srcTrans,
+ std::shared_ptr<TTransport> dstTrans)
: TPipedTransport(srcTrans, dstTrans), srcTrans_(srcTrans) {
}
-TPipedFileReaderTransport::~TPipedFileReaderTransport() {
-}
+TPipedFileReaderTransport::~TPipedFileReaderTransport() = default;
-bool TPipedFileReaderTransport::isOpen() {
+bool TPipedFileReaderTransport::isOpen() const {
return TPipedTransport::isOpen();
}
diff --git a/lib/cpp/src/thrift/transport/TTransportUtils.h b/lib/cpp/src/thrift/transport/TTransportUtils.h
index f3b4c5a..28c93d2 100644
--- a/lib/cpp/src/thrift/transport/TTransportUtils.h
+++ b/lib/cpp/src/thrift/transport/TTransportUtils.h
@@ -42,13 +42,13 @@
*/
class TNullTransport : public TVirtualTransport<TNullTransport> {
public:
- TNullTransport() {}
+ TNullTransport() = default;
- ~TNullTransport() {}
+ ~TNullTransport() override = default;
- bool isOpen() { return true; }
+ bool isOpen() const override { return true; }
- void open() {}
+ void open() override {}
void write(const uint8_t* /* buf */, uint32_t /* len */) { return; }
};
@@ -63,7 +63,7 @@
*/
class TPipedTransport : virtual public TTransport {
public:
- TPipedTransport(stdcxx::shared_ptr<TTransport> srcTrans, stdcxx::shared_ptr<TTransport> dstTrans)
+ TPipedTransport(std::shared_ptr<TTransport> srcTrans, std::shared_ptr<TTransport> dstTrans)
: srcTrans_(srcTrans),
dstTrans_(dstTrans),
rBufSize_(512),
@@ -77,17 +77,17 @@
pipeOnWrite_ = false;
rBuf_ = (uint8_t*)std::malloc(sizeof(uint8_t) * rBufSize_);
- if (rBuf_ == NULL) {
+ if (rBuf_ == nullptr) {
throw std::bad_alloc();
}
wBuf_ = (uint8_t*)std::malloc(sizeof(uint8_t) * wBufSize_);
- if (wBuf_ == NULL) {
+ if (wBuf_ == nullptr) {
throw std::bad_alloc();
}
}
- TPipedTransport(stdcxx::shared_ptr<TTransport> srcTrans,
- stdcxx::shared_ptr<TTransport> dstTrans,
+ TPipedTransport(std::shared_ptr<TTransport> srcTrans,
+ std::shared_ptr<TTransport> dstTrans,
uint32_t sz)
: srcTrans_(srcTrans),
dstTrans_(dstTrans),
@@ -98,29 +98,29 @@
wLen_(0) {
rBuf_ = (uint8_t*)std::malloc(sizeof(uint8_t) * rBufSize_);
- if (rBuf_ == NULL) {
+ if (rBuf_ == nullptr) {
throw std::bad_alloc();
}
wBuf_ = (uint8_t*)std::malloc(sizeof(uint8_t) * wBufSize_);
- if (wBuf_ == NULL) {
+ if (wBuf_ == nullptr) {
throw std::bad_alloc();
}
}
- ~TPipedTransport() {
+ ~TPipedTransport() override {
std::free(rBuf_);
std::free(wBuf_);
}
- bool isOpen() { return srcTrans_->isOpen(); }
+ bool isOpen() const override { return srcTrans_->isOpen(); }
- bool peek() {
+ bool peek() override {
if (rPos_ >= rLen_) {
// Double the size of the underlying buffer if it is full
if (rLen_ == rBufSize_) {
rBufSize_ *= 2;
- uint8_t * tmpBuf = (uint8_t*)std::realloc(rBuf_, sizeof(uint8_t) * rBufSize_);
- if (tmpBuf == NULL) {
+ auto * tmpBuf = (uint8_t*)std::realloc(rBuf_, sizeof(uint8_t) * rBufSize_);
+ if (tmpBuf == nullptr) {
throw std::bad_alloc();
}
rBuf_ = tmpBuf;
@@ -132,9 +132,9 @@
return (rLen_ > rPos_);
}
- void open() { srcTrans_->open(); }
+ void open() override { srcTrans_->open(); }
- void close() { srcTrans_->close(); }
+ void close() override { srcTrans_->close(); }
void setPipeOnRead(bool pipeVal) { pipeOnRead_ = pipeVal; }
@@ -142,7 +142,7 @@
uint32_t read(uint8_t* buf, uint32_t len);
- uint32_t readEnd() {
+ uint32_t readEnd() override {
if (pipeOnRead_) {
dstTrans_->write(rBuf_, rPos_);
@@ -164,7 +164,7 @@
void write(const uint8_t* buf, uint32_t len);
- uint32_t writeEnd() {
+ uint32_t writeEnd() override {
if (pipeOnWrite_) {
dstTrans_->write(wBuf_, wLen_);
dstTrans_->flush();
@@ -172,21 +172,21 @@
return wLen_;
}
- void flush();
+ void flush() override;
- stdcxx::shared_ptr<TTransport> getTargetTransport() { return dstTrans_; }
+ std::shared_ptr<TTransport> getTargetTransport() { return dstTrans_; }
/*
* Override TTransport *_virt() functions to invoke our implementations.
* We cannot use TVirtualTransport to provide these, since we need to inherit
* virtually from TTransport.
*/
- virtual uint32_t read_virt(uint8_t* buf, uint32_t len) { return this->read(buf, len); }
- virtual void write_virt(const uint8_t* buf, uint32_t len) { this->write(buf, len); }
+ uint32_t read_virt(uint8_t* buf, uint32_t len) override { return this->read(buf, len); }
+ void write_virt(const uint8_t* buf, uint32_t len) override { this->write(buf, len); }
protected:
- stdcxx::shared_ptr<TTransport> srcTrans_;
- stdcxx::shared_ptr<TTransport> dstTrans_;
+ std::shared_ptr<TTransport> srcTrans_;
+ std::shared_ptr<TTransport> dstTrans_;
uint8_t* rBuf_;
uint32_t rBufSize_;
@@ -207,21 +207,21 @@
*/
class TPipedTransportFactory : public TTransportFactory {
public:
- TPipedTransportFactory() {}
- TPipedTransportFactory(stdcxx::shared_ptr<TTransport> dstTrans) {
+ TPipedTransportFactory() = default;
+ TPipedTransportFactory(std::shared_ptr<TTransport> dstTrans) {
initializeTargetTransport(dstTrans);
}
- virtual ~TPipedTransportFactory() {}
+ ~TPipedTransportFactory() override = default;
/**
* Wraps the base transport into a piped transport.
*/
- virtual stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> srcTrans) {
- return stdcxx::shared_ptr<TTransport>(new TPipedTransport(srcTrans, dstTrans_));
+ std::shared_ptr<TTransport> getTransport(std::shared_ptr<TTransport> srcTrans) override {
+ return std::shared_ptr<TTransport>(new TPipedTransport(srcTrans, dstTrans_));
}
- virtual void initializeTargetTransport(stdcxx::shared_ptr<TTransport> dstTrans) {
- if (dstTrans_.get() == NULL) {
+ virtual void initializeTargetTransport(std::shared_ptr<TTransport> dstTrans) {
+ if (dstTrans_.get() == nullptr) {
dstTrans_ = dstTrans;
} else {
throw TException("Target transport already initialized");
@@ -229,7 +229,7 @@
}
protected:
- stdcxx::shared_ptr<TTransport> dstTrans_;
+ std::shared_ptr<TTransport> dstTrans_;
};
/**
@@ -240,44 +240,44 @@
*/
class TPipedFileReaderTransport : public TPipedTransport, public TFileReaderTransport {
public:
- TPipedFileReaderTransport(stdcxx::shared_ptr<TFileReaderTransport> srcTrans,
- stdcxx::shared_ptr<TTransport> dstTrans);
+ TPipedFileReaderTransport(std::shared_ptr<TFileReaderTransport> srcTrans,
+ std::shared_ptr<TTransport> dstTrans);
- ~TPipedFileReaderTransport();
+ ~TPipedFileReaderTransport() override;
// TTransport functions
- bool isOpen();
- bool peek();
- void open();
- void close();
+ bool isOpen() const override;
+ bool peek() override;
+ void open() override;
+ void close() override;
uint32_t read(uint8_t* buf, uint32_t len);
uint32_t readAll(uint8_t* buf, uint32_t len);
- uint32_t readEnd();
+ uint32_t readEnd() override;
void write(const uint8_t* buf, uint32_t len);
- uint32_t writeEnd();
- void flush();
+ uint32_t writeEnd() override;
+ void flush() override;
// TFileReaderTransport functions
- int32_t getReadTimeout();
- void setReadTimeout(int32_t readTimeout);
- uint32_t getNumChunks();
- uint32_t getCurChunk();
- void seekToChunk(int32_t chunk);
- void seekToEnd();
+ int32_t getReadTimeout() override;
+ void setReadTimeout(int32_t readTimeout) override;
+ uint32_t getNumChunks() override;
+ uint32_t getCurChunk() override;
+ void seekToChunk(int32_t chunk) override;
+ void seekToEnd() override;
/*
* Override TTransport *_virt() functions to invoke our implementations.
* We cannot use TVirtualTransport to provide these, since we need to inherit
* virtually from TTransport.
*/
- virtual uint32_t read_virt(uint8_t* buf, uint32_t len) { return this->read(buf, len); }
- virtual uint32_t readAll_virt(uint8_t* buf, uint32_t len) { return this->readAll(buf, len); }
- virtual void write_virt(const uint8_t* buf, uint32_t len) { this->write(buf, len); }
+ uint32_t read_virt(uint8_t* buf, uint32_t len) override { return this->read(buf, len); }
+ uint32_t readAll_virt(uint8_t* buf, uint32_t len) override { return this->readAll(buf, len); }
+ void write_virt(const uint8_t* buf, uint32_t len) override { this->write(buf, len); }
protected:
// shouldn't be used
TPipedFileReaderTransport();
- stdcxx::shared_ptr<TFileReaderTransport> srcTrans_;
+ std::shared_ptr<TFileReaderTransport> srcTrans_;
};
/**
@@ -286,24 +286,24 @@
*/
class TPipedFileReaderTransportFactory : public TPipedTransportFactory {
public:
- TPipedFileReaderTransportFactory() {}
- TPipedFileReaderTransportFactory(stdcxx::shared_ptr<TTransport> dstTrans)
+ TPipedFileReaderTransportFactory() = default;
+ TPipedFileReaderTransportFactory(std::shared_ptr<TTransport> dstTrans)
: TPipedTransportFactory(dstTrans) {}
- virtual ~TPipedFileReaderTransportFactory() {}
+ ~TPipedFileReaderTransportFactory() override = default;
- stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> srcTrans) {
- stdcxx::shared_ptr<TFileReaderTransport> pFileReaderTransport
- = stdcxx::dynamic_pointer_cast<TFileReaderTransport>(srcTrans);
- if (pFileReaderTransport.get() != NULL) {
+ std::shared_ptr<TTransport> getTransport(std::shared_ptr<TTransport> srcTrans) override {
+ std::shared_ptr<TFileReaderTransport> pFileReaderTransport
+ = std::dynamic_pointer_cast<TFileReaderTransport>(srcTrans);
+ if (pFileReaderTransport.get() != nullptr) {
return getFileReaderTransport(pFileReaderTransport);
} else {
- return stdcxx::shared_ptr<TTransport>();
+ return std::shared_ptr<TTransport>();
}
}
- stdcxx::shared_ptr<TFileReaderTransport> getFileReaderTransport(
- stdcxx::shared_ptr<TFileReaderTransport> srcTrans) {
- return stdcxx::shared_ptr<TFileReaderTransport>(
+ std::shared_ptr<TFileReaderTransport> getFileReaderTransport(
+ std::shared_ptr<TFileReaderTransport> srcTrans) {
+ return std::shared_ptr<TFileReaderTransport>(
new TPipedFileReaderTransport(srcTrans, dstTrans_));
}
};
diff --git a/lib/cpp/src/thrift/transport/TVirtualTransport.h b/lib/cpp/src/thrift/transport/TVirtualTransport.h
index 0cacf61..0a04857 100644
--- a/lib/cpp/src/thrift/transport/TVirtualTransport.h
+++ b/lib/cpp/src/thrift/transport/TVirtualTransport.h
@@ -57,7 +57,7 @@
void consume(uint32_t len) { this->TTransport::consume_virt(len); }
protected:
- TTransportDefaults() {}
+ TTransportDefaults() = default;
};
/**
@@ -84,23 +84,23 @@
* Implementations of the *_virt() functions, to call the subclass's
* non-virtual implementation function.
*/
- virtual uint32_t read_virt(uint8_t* buf, uint32_t len) {
+ uint32_t read_virt(uint8_t* buf, uint32_t len) override {
return static_cast<Transport_*>(this)->read(buf, len);
}
- virtual uint32_t readAll_virt(uint8_t* buf, uint32_t len) {
+ uint32_t readAll_virt(uint8_t* buf, uint32_t len) override {
return static_cast<Transport_*>(this)->readAll(buf, len);
}
- virtual void write_virt(const uint8_t* buf, uint32_t len) {
+ void write_virt(const uint8_t* buf, uint32_t len) override {
static_cast<Transport_*>(this)->write(buf, len);
}
- virtual const uint8_t* borrow_virt(uint8_t* buf, uint32_t* len) {
+ const uint8_t* borrow_virt(uint8_t* buf, uint32_t* len) override {
return static_cast<Transport_*>(this)->borrow(buf, len);
}
- virtual void consume_virt(uint32_t len) { static_cast<Transport_*>(this)->consume(len); }
+ void consume_virt(uint32_t len) override { static_cast<Transport_*>(this)->consume(len); }
/*
* Provide a default readAll() implementation that invokes
@@ -113,12 +113,12 @@
* the correct parent implementation, if desired.
*/
uint32_t readAll(uint8_t* buf, uint32_t len) {
- Transport_* trans = static_cast<Transport_*>(this);
+ auto* trans = static_cast<Transport_*>(this);
return ::apache::thrift::transport::readAll(*trans, buf, len);
}
protected:
- TVirtualTransport() {}
+ TVirtualTransport() = default;
/*
* Templatized constructors, to allow arguments to be passed to the Super_
diff --git a/lib/cpp/src/thrift/transport/TZlibTransport.cpp b/lib/cpp/src/thrift/transport/TZlibTransport.cpp
index e426dc3..437190b 100644
--- a/lib/cpp/src/thrift/transport/TZlibTransport.cpp
+++ b/lib/cpp/src/thrift/transport/TZlibTransport.cpp
@@ -110,7 +110,7 @@
delete wstream_;
}
-bool TZlibTransport::isOpen() {
+bool TZlibTransport::isOpen() const {
return (readAvail() > 0) || (rstream_->avail_in > 0) || transport_->isOpen();
}
@@ -131,7 +131,7 @@
// In standalone objects, we set input_ended_ to true when inflate returns
// Z_STREAM_END. This allows to make sure that a checksum was verified.
-inline int TZlibTransport::readAvail() {
+inline int TZlibTransport::readAvail() const {
return urbuf_size_ - rstream_->avail_out - urpos_;
}
@@ -331,7 +331,7 @@
*len = (uint32_t)readAvail();
return urbuf_ + urpos_;
}
- return NULL;
+ return nullptr;
}
void TZlibTransport::consume(uint32_t len) {
diff --git a/lib/cpp/src/thrift/transport/TZlibTransport.h b/lib/cpp/src/thrift/transport/TZlibTransport.h
index a0fb464..29afae0 100644
--- a/lib/cpp/src/thrift/transport/TZlibTransport.h
+++ b/lib/cpp/src/thrift/transport/TZlibTransport.h
@@ -36,9 +36,9 @@
TZlibTransportException(int status, const char* msg)
: TTransportException(TTransportException::INTERNAL_ERROR, errorMessage(status, msg)),
zlib_status_(status),
- zlib_msg_(msg == NULL ? "(null)" : msg) {}
+ zlib_msg_(msg == nullptr ? "(null)" : msg) {}
- virtual ~TZlibTransportException() throw() {}
+ ~TZlibTransportException() noexcept override = default;
int getZlibStatus() { return zlib_status_; }
std::string getZlibMessage() { return zlib_msg_; }
@@ -78,7 +78,7 @@
* @param cwbuf_size Compressed buffer size for writing.
* @param comp_level Compression level (0=none[fast], 6=default, 9=max[slow]).
*/
- TZlibTransport(stdcxx::shared_ptr<TTransport> transport,
+ TZlibTransport(std::shared_ptr<TTransport> transport,
int urbuf_size = DEFAULT_URBUF_SIZE,
int crbuf_size = DEFAULT_CRBUF_SIZE,
int uwbuf_size = DEFAULT_UWBUF_SIZE,
@@ -93,12 +93,12 @@
crbuf_size_(crbuf_size),
uwbuf_size_(uwbuf_size),
cwbuf_size_(cwbuf_size),
- urbuf_(NULL),
- crbuf_(NULL),
- uwbuf_(NULL),
- cwbuf_(NULL),
- rstream_(NULL),
- wstream_(NULL),
+ urbuf_(nullptr),
+ crbuf_(nullptr),
+ uwbuf_(nullptr),
+ cwbuf_(nullptr),
+ rstream_(nullptr),
+ wstream_(nullptr),
comp_level_(comp_level) {
if (uwbuf_size_ < MIN_DIRECT_DEFLATE_SIZE) {
// Have to copy this into a local because of a linking issue.
@@ -136,20 +136,20 @@
* unflushed data. You must explicitly call flush() or finish() to ensure
* that data is actually written and flushed to the underlying transport.
*/
- ~TZlibTransport();
+ ~TZlibTransport() override;
- bool isOpen();
- bool peek();
+ bool isOpen() const override;
+ bool peek() override;
- void open() { transport_->open(); }
+ void open() override { transport_->open(); }
- void close() { transport_->close(); }
+ void close() override { transport_->close(); }
uint32_t read(uint8_t* buf, uint32_t len);
void write(const uint8_t* buf, uint32_t len);
- void flush();
+ void flush() override;
/**
* Finalize the zlib stream.
@@ -180,12 +180,12 @@
static const int DEFAULT_UWBUF_SIZE = 128;
static const int DEFAULT_CWBUF_SIZE = 1024;
- stdcxx::shared_ptr<TTransport> getUnderlyingTransport() const { return transport_; }
+ std::shared_ptr<TTransport> getUnderlyingTransport() const { return transport_; }
protected:
inline void checkZlibRv(int status, const char* msg);
inline void checkZlibRvNothrow(int status, const char* msg);
- inline int readAvail();
+ inline int readAvail() const;
void flushToTransport(int flush);
void flushToZlib(const uint8_t* buf, int len, int flush);
bool readFromZlib();
@@ -195,7 +195,7 @@
// Larger (or equal) writes are dumped straight to zlib.
static const uint32_t MIN_DIRECT_DEFLATE_SIZE = 32;
- stdcxx::shared_ptr<TTransport> transport_;
+ std::shared_ptr<TTransport> transport_;
int urpos_;
int uwpos_;
@@ -227,12 +227,12 @@
*/
class TZlibTransportFactory : public TTransportFactory {
public:
- TZlibTransportFactory() {}
+ TZlibTransportFactory() = default;
- virtual ~TZlibTransportFactory() {}
+ ~TZlibTransportFactory() override = default;
- virtual stdcxx::shared_ptr<TTransport> getTransport(stdcxx::shared_ptr<TTransport> trans) {
- return stdcxx::shared_ptr<TTransport>(new TZlibTransport(trans));
+ std::shared_ptr<TTransport> getTransport(std::shared_ptr<TTransport> trans) override {
+ return std::shared_ptr<TTransport>(new TZlibTransport(trans));
}
};
}
diff --git a/lib/cpp/src/thrift/windows/GetTimeOfDay.cpp b/lib/cpp/src/thrift/windows/GetTimeOfDay.cpp
index 820828f..0a0292c 100644
--- a/lib/cpp/src/thrift/windows/GetTimeOfDay.cpp
+++ b/lib/cpp/src/thrift/windows/GetTimeOfDay.cpp
@@ -25,12 +25,6 @@
#include <sys/time.h>
#endif
-#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
-#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
-#else
-#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
-#endif
-
#if !defined(__MINGW32__)
struct timezone {
int tz_minuteswest; /* minutes W of Greenwich */
@@ -43,50 +37,45 @@
return gettimeofday(tv,tz);
}
#else
-int thrift_gettimeofday(struct timeval* tv, struct timezone* tz) {
- FILETIME ft;
- unsigned __int64 tmpres(0);
- static int tzflag;
+#define WIN32_LEAN_AND_MEAN
+#include <Winsock2.h>
+#include <cstdint>
+#include <sstream>
+#include <thrift/transport/TTransportException.h>
- if (NULL != tv) {
- GetSystemTimeAsFileTime(&ft);
+// This code started from a "FREE implementation" posted to Stack Overflow at:
+// https://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows
+// added: assert
+// added: error handling
+// added: C++ style casts
+int thrift_gettimeofday(struct timeval * tp, struct timezone * tzp)
+{
+ // We don't fill it in so prove nobody is looking for the data
+ assert(tzp == NULL);
- tmpres |= ft.dwHighDateTime;
- tmpres <<= 32;
- tmpres |= ft.dwLowDateTime;
+ // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
+ // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
+ // until 00:00:00 January 1, 1970
+ static const uint64_t EPOCH = static_cast<uint64_t>(116444736000000000ULL);
- /*converting file time to unix epoch*/
- tmpres -= DELTA_EPOCH_IN_MICROSECS;
- tmpres /= 10; /*convert into microseconds*/
- tv->tv_sec = (long)(tmpres / 1000000UL);
- tv->tv_usec = (long)(tmpres % 1000000UL);
- }
+ SYSTEMTIME system_time;
+ FILETIME file_time;
+ uint64_t time;
- if (NULL != tz) {
- if (!tzflag) {
- _tzset();
- tzflag++;
+ GetSystemTime( &system_time );
+ if (!SystemTimeToFileTime( &system_time, &file_time )) {
+ DWORD lastError = GetLastError();
+ std::stringstream ss;
+ ss << "SystemTimeToFileTime failed: 0x" << std::hex << lastError;
+ using apache::thrift::transport::TTransportException;
+ throw TTransportException(TTransportException::INTERNAL_ERROR, ss.str());
}
+ time = static_cast<uint64_t>(file_time.dwLowDateTime ) ;
+ time += static_cast<uint64_t>(file_time.dwHighDateTime) << 32;
- long time_zone(0);
- errno_t err(_get_timezone(&time_zone));
- if (err == NO_ERROR) {
- tz->tz_minuteswest = time_zone / 60;
- } else {
- return -1;
- }
-
- int day_light(0);
- err = (_get_daylight(&day_light));
- if (err == NO_ERROR) {
- tz->tz_dsttime = day_light;
- return 0;
- } else {
- return -1;
- }
- }
-
- return 0;
+ tp->tv_sec = static_cast<long>((time - EPOCH) / 10000000L);
+ tp->tv_usec = static_cast<long>(system_time.wMilliseconds * 1000);
+ return 0;
}
#endif
diff --git a/lib/cpp/src/thrift/windows/TWinsockSingleton.cpp b/lib/cpp/src/thrift/windows/TWinsockSingleton.cpp
index 2e0ccf5..a502cbd 100644
--- a/lib/cpp/src/thrift/windows/TWinsockSingleton.cpp
+++ b/lib/cpp/src/thrift/windows/TWinsockSingleton.cpp
@@ -20,7 +20,6 @@
#include <thrift/windows/TWinsockSingleton.h>
// boost
-#include <boost/assert.hpp>
#include <stdexcept>
namespace apache {
@@ -28,13 +27,7 @@
namespace transport {
TWinsockSingleton::instance_ptr TWinsockSingleton::instance_ptr_(NULL);
-#if USE_BOOST_THREAD
-boost::once_flag TWinsockSingleton::flags_ = BOOST_ONCE_INIT;
-#elif USE_STD_THREAD
std::once_flag TWinsockSingleton::flags_;
-#else
-#error For windows you must choose USE_BOOST_THREAD or USE_STD_THREAD
-#endif
//------------------------------------------------------------------------------
TWinsockSingleton::TWinsockSingleton(void) {
@@ -43,7 +36,6 @@
int error(WSAStartup(version, &data));
if (error != 0) {
- BOOST_ASSERT(false);
throw std::runtime_error("Failed to initialise Winsock.");
}
}
@@ -55,11 +47,7 @@
//------------------------------------------------------------------------------
void TWinsockSingleton::create(void) {
-#if USE_BOOST_THREAD
- boost::call_once(init, flags_);
-#elif USE_STD_THREAD
std::call_once(flags_, init);
-#endif
}
//------------------------------------------------------------------------------
diff --git a/lib/cpp/src/thrift/windows/TWinsockSingleton.h b/lib/cpp/src/thrift/windows/TWinsockSingleton.h
index 0eab6d4..a30806b 100644
--- a/lib/cpp/src/thrift/windows/TWinsockSingleton.h
+++ b/lib/cpp/src/thrift/windows/TWinsockSingleton.h
@@ -33,15 +33,9 @@
// boost
#include <boost/noncopyable.hpp>
-#if USE_BOOST_THREAD
-#include <boost/thread/once.hpp>
-#elif USE_STD_THREAD
+#include <memory>
#include <mutex>
-#else
-#error For windows you must choose USE_BOOST_THREAD or USE_STD_THREAD
-#endif
-#include <thrift/stdcxx.h>
namespace apache {
namespace thrift {
@@ -54,7 +48,7 @@
class TWinsockSingleton : private boost::noncopyable {
public:
- typedef stdcxx::shared_ptr<TWinsockSingleton> instance_ptr;
+ typedef std::shared_ptr<TWinsockSingleton> instance_ptr;
private:
TWinsockSingleton(void);
@@ -70,13 +64,7 @@
private:
static instance_ptr instance_ptr_;
-#if USE_BOOST_THREAD
- static boost::once_flag flags_;
-#elif USE_STD_THREAD
static std::once_flag flags_;
-#else
-#error Need a non-Boost non-C++11 way to track single initialization here.
-#endif
};
}
}
diff --git a/lib/cpp/src/thrift/windows/config.h b/lib/cpp/src/thrift/windows/config.h
index bc4aa42..063a92a 100644
--- a/lib/cpp/src/thrift/windows/config.h
+++ b/lib/cpp/src/thrift/windows/config.h
@@ -28,35 +28,9 @@
#error "This is a Windows header only"
#endif
-// use std::thread in MSVC11 (2012) or newer and in MinGW
-#if (_MSC_VER >= 1700) || defined(__MINGW32__)
-#define USE_STD_THREAD 1
-#else
-// otherwise use boost threads
-#define USE_BOOST_THREAD 1
-#endif
-
// Something that defines PRId64 is required to build
#define HAVE_INTTYPES_H 1
-// VS2010 or later has stdint.h as does MinGW
-#if (_MSC_VER >= 1600) || defined(__MINGW32__)
-#define HAVE_STDINT_H 1
-#endif
-
-#ifndef TARGET_WIN_XP
-#define TARGET_WIN_XP 1
-#endif
-
-#if TARGET_WIN_XP
-#ifndef WINVER
-#define WINVER 0x0501
-#endif
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501
-#endif
-#endif
-
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0601
#endif
@@ -73,21 +47,7 @@
#define HAVE_GETTIMEOFDAY 1
#define HAVE_SYS_STAT_H 1
-// Must be using VS2010 or later, or boost, so that C99 types are defined in the global namespace
-#ifdef HAVE_STDINT_H
#include <stdint.h>
-#else
-#include <boost/cstdint.hpp>
-
-typedef boost::int64_t int64_t;
-typedef boost::uint64_t uint64_t;
-typedef boost::int32_t int32_t;
-typedef boost::uint32_t uint32_t;
-typedef boost::int16_t int16_t;
-typedef boost::uint16_t uint16_t;
-typedef boost::int8_t int8_t;
-typedef boost::uint8_t uint8_t;
-#endif
#include <thrift/transport/PlatformSocket.h>
#include <thrift/windows/GetTimeOfDay.h>
diff --git a/lib/cpp/test/AllProtocolTests.tcc b/lib/cpp/test/AllProtocolTests.tcc
index b6df656..80a4ea0 100644
--- a/lib/cpp/test/AllProtocolTests.tcc
+++ b/lib/cpp/test/AllProtocolTests.tcc
@@ -28,7 +28,7 @@
#include "GenericHelpers.h"
-using apache::thrift::stdcxx::shared_ptr;
+using std::shared_ptr;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
@@ -216,7 +216,7 @@
testMessage<TProto>();
printf("%s => OK\n", protoname);
- } catch (TException e) {
+ } catch (const TException &e) {
THRIFT_SNPRINTF(errorMessage, ERR_LEN, "%s => Test FAILED: %s", protoname, e.what());
throw TException(errorMessage);
}
diff --git a/lib/cpp/test/Benchmark.cpp b/lib/cpp/test/Benchmark.cpp
index afde7d4..56adac0 100644
--- a/lib/cpp/test/Benchmark.cpp
+++ b/lib/cpp/test/Benchmark.cpp
@@ -23,8 +23,8 @@
#include <iostream>
#define _USE_MATH_DEFINES
#include <math.h>
+#include <memory>
#include "thrift/protocol/TBinaryProtocol.h"
-#include "thrift/stdcxx.h"
#include "thrift/transport/TBufferTransports.h"
#include "gen-cpp/DebugProtoTest_types.h"
@@ -36,12 +36,12 @@
public:
timeval vStart;
- Timer() { THRIFT_GETTIMEOFDAY(&vStart, 0); }
- void start() { THRIFT_GETTIMEOFDAY(&vStart, 0); }
+ Timer() { THRIFT_GETTIMEOFDAY(&vStart, nullptr); }
+ void start() { THRIFT_GETTIMEOFDAY(&vStart, nullptr); }
double frame() {
timeval vEnd;
- THRIFT_GETTIMEOFDAY(&vEnd, 0);
+ THRIFT_GETTIMEOFDAY(&vEnd, nullptr);
double dstart = vStart.tv_sec + ((double)vStart.tv_usec / 1000000.0);
double dend = vEnd.tv_sec + ((double)vEnd.tv_usec / 1000000.0);
return dend - dstart;
@@ -68,9 +68,9 @@
ooe.base64 = "\1\2\3\255";
int num = 100000;
- apache::thrift::stdcxx::shared_ptr<TMemoryBuffer> buf(new TMemoryBuffer(num*1000));
+ std::shared_ptr<TMemoryBuffer> buf(new TMemoryBuffer(num*1000));
- uint8_t* data = NULL;
+ uint8_t* data = nullptr;
uint32_t datasize = 0;
{
@@ -89,7 +89,7 @@
buf->getBuffer(&data, &datasize);
{
- apache::thrift::stdcxx::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
+ std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
TBinaryProtocolT<TMemoryBuffer> prot(buf2);
OneOfEach ooe2;
double elapsed = 0.0;
@@ -117,7 +117,7 @@
{
OneOfEach ooe2;
- apache::thrift::stdcxx::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
+ std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
TBinaryProtocolT<TMemoryBuffer, TNetworkLittleEndian> prot(buf2);
double elapsed = 0.0;
Timer timer;
@@ -143,7 +143,7 @@
}
{
- apache::thrift::stdcxx::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
+ std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
TBinaryProtocolT<TMemoryBuffer> prot(buf2);
OneOfEach ooe2;
double elapsed = 0.0;
@@ -157,7 +157,7 @@
}
- data = NULL;
+ data = nullptr;
datasize = 0;
num = 10000000;
@@ -182,7 +182,7 @@
buf->getBuffer(&data, &datasize);
{
- apache::thrift::stdcxx::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
+ std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
TBinaryProtocolT<TMemoryBuffer> prot(buf2);
ListDoublePerf listDoublePerf2;
double elapsed = 0.0;
@@ -206,7 +206,7 @@
{
ListDoublePerf listDoublePerf2;
- apache::thrift::stdcxx::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
+ std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
TBinaryProtocolT<TMemoryBuffer, TNetworkLittleEndian> prot(buf2);
double elapsed = 0.0;
Timer timer;
@@ -228,7 +228,7 @@
}
{
- apache::thrift::stdcxx::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
+ std::shared_ptr<TMemoryBuffer> buf2(new TMemoryBuffer(data, datasize));
TBinaryProtocolT<TMemoryBuffer> prot(buf2);
ListDoublePerf listDoublePerf2;
double elapsed = 0.0;
diff --git a/lib/cpp/test/CMakeLists.txt b/lib/cpp/test/CMakeLists.txt
index 261382f..ef08dbc 100644
--- a/lib/cpp/test/CMakeLists.txt
+++ b/lib/cpp/test/CMakeLists.txt
@@ -17,11 +17,13 @@
# under the License.
#
-include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
+# Unit tests still require boost
+include(BoostMacros)
+REQUIRE_BOOST_HEADERS()
+set(BOOST_COMPONENTS chrono date_time filesystem random thread unit_test_framework)
+REQUIRE_BOOST_LIBRARIES(BOOST_COMPONENTS)
-if (WITH_DYN_LINK_TEST)
- add_definitions( -DBOOST_TEST_DYN_LINK )
-endif()
+include(ThriftMacros)
# Make sure gen-cpp files can be included
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
@@ -82,11 +84,6 @@
TServerTransportTest.cpp
)
-if(NOT WITH_BOOSTTHREADS AND NOT WITH_STDTHREADS AND NOT MSVC AND NOT MINGW)
- list(APPEND UnitTest_SOURCES concurrency/MutexTest.cpp)
- list(APPEND UnitTest_SOURCES concurrency/RWMutexStarveTest.cpp)
-endif()
-
add_executable(UnitTests ${UnitTest_SOURCES})
target_link_libraries(UnitTests testgencpp ${Boost_LIBRARIES})
LINK_AGAINST_THRIFT_LIBRARY(UnitTests thrift)
@@ -339,18 +336,6 @@
endif()
-if(WITH_QT4)
-set(CMAKE_AUTOMOC ON)
-find_package(Qt4 REQUIRED COMPONENTS QtTest)
-set(TQTcpServerTest_SOURCES
- qt/TQTcpServerTest.cpp
-)
-add_executable(TQTcpServerTest ${TQTcpServerTest_SOURCES})
-target_link_libraries(TQTcpServerTest testgencpp_cob thriftqt Qt4::QtTest)
-LINK_AGAINST_THRIFT_LIBRARY(TQTcpServerTest thrift)
-add_test(NAME TQTcpServerTest COMMAND TQTcpServerTest)
-endif()
-
if(WITH_QT5)
add_subdirectory(qt)
endif()
diff --git a/lib/cpp/test/DebugProtoTest.cpp b/lib/cpp/test/DebugProtoTest.cpp
index e04600a..060f354 100644
--- a/lib/cpp/test/DebugProtoTest.cpp
+++ b/lib/cpp/test/DebugProtoTest.cpp
@@ -21,14 +21,14 @@
#include <cmath>
#include "gen-cpp/DebugProtoTest_types.h"
#include <thrift/protocol/TDebugProtocol.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#define BOOST_TEST_MODULE DebugProtoTest
#include <boost/test/unit_test.hpp>
using namespace thrift::test::debug;
-static ::apache::thrift::stdcxx::shared_ptr<OneOfEach> ooe;
+static ::std::shared_ptr<OneOfEach> ooe;
void testCaseSetup_1() {
ooe.reset(new OneOfEach);
@@ -81,7 +81,7 @@
"Expected:\n" << expected_result << "\nGotten:\n" << result);
}
-static ::apache::thrift::stdcxx::shared_ptr<Nesting> n;
+static ::std::shared_ptr<Nesting> n;
void testCaseSetup_2() {
testCaseSetup_1();
@@ -149,7 +149,7 @@
"Expected:\n" << expected_result << "\nGotten:\n" << result);
}
-static ::apache::thrift::stdcxx::shared_ptr<HolyMoley> hm;
+static ::std::shared_ptr<HolyMoley> hm;
void testCaseSetup_3() {
testCaseSetup_2();
diff --git a/lib/cpp/test/EnumTest.cpp b/lib/cpp/test/EnumTest.cpp
index c935bc4..6487906 100644
--- a/lib/cpp/test/EnumTest.cpp
+++ b/lib/cpp/test/EnumTest.cpp
@@ -75,7 +75,7 @@
BOOST_CHECK_EQUAL(EnumToString(MyEnumWithCustomOstream::CustoM2), "{2:CUSTOM!}");
// some invalid or unknown value
- MyEnum5::type uut = (MyEnum5::type)44;
+ auto uut = (MyEnum5::type)44;
BOOST_CHECK_EQUAL(EnumToString(uut), "44");
}
diff --git a/lib/cpp/test/GenericHelpers.h b/lib/cpp/test/GenericHelpers.h
index e131c42..bcef9f2 100644
--- a/lib/cpp/test/GenericHelpers.h
+++ b/lib/cpp/test/GenericHelpers.h
@@ -21,7 +21,7 @@
#define _THRIFT_TEST_GENERICHELPERS_H_ 1
#include <thrift/protocol/TProtocol.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/Thrift.h>
/* ClassName Helper for cleaner exceptions */
@@ -63,43 +63,43 @@
public:
/* Write functions */
- static uint32_t write(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, const int8_t& val) {
+ static uint32_t write(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, const int8_t& val) {
return proto->writeByte(val);
}
- static uint32_t write(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, const int16_t& val) {
+ static uint32_t write(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, const int16_t& val) {
return proto->writeI16(val);
}
- static uint32_t write(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, const int32_t& val) {
+ static uint32_t write(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, const int32_t& val) {
return proto->writeI32(val);
}
- static uint32_t write(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, const double& val) {
+ static uint32_t write(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, const double& val) {
return proto->writeDouble(val);
}
- static uint32_t write(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, const int64_t& val) {
+ static uint32_t write(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, const int64_t& val) {
return proto->writeI64(val);
}
- static uint32_t write(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, const std::string& val) {
+ static uint32_t write(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, const std::string& val) {
return proto->writeString(val);
}
/* Read functions */
- static uint32_t read(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, int8_t& val) { return proto->readByte(val); }
+ static uint32_t read(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, int8_t& val) { return proto->readByte(val); }
- static uint32_t read(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, int16_t& val) { return proto->readI16(val); }
+ static uint32_t read(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, int16_t& val) { return proto->readI16(val); }
- static uint32_t read(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, int32_t& val) { return proto->readI32(val); }
+ static uint32_t read(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, int32_t& val) { return proto->readI32(val); }
- static uint32_t read(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, int64_t& val) { return proto->readI64(val); }
+ static uint32_t read(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, int64_t& val) { return proto->readI64(val); }
- static uint32_t read(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, double& val) { return proto->readDouble(val); }
+ static uint32_t read(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, double& val) { return proto->readDouble(val); }
- static uint32_t read(apache::thrift::stdcxx::shared_ptr<apache::thrift::protocol::TProtocol> proto, std::string& val) {
+ static uint32_t read(std::shared_ptr<apache::thrift::protocol::TProtocol> proto, std::string& val) {
return proto->readString(val);
}
};
diff --git a/lib/cpp/test/JSONProtoTest.cpp b/lib/cpp/test/JSONProtoTest.cpp
index 77bc250..c2ad73e 100644
--- a/lib/cpp/test/JSONProtoTest.cpp
+++ b/lib/cpp/test/JSONProtoTest.cpp
@@ -22,7 +22,7 @@
#include <iomanip>
#include <sstream>
#include <thrift/protocol/TJSONProtocol.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/transport/TBufferTransports.h>
#include "gen-cpp/DebugProtoTest_types.h"
@@ -34,7 +34,7 @@
using apache::thrift::transport::TMemoryBuffer;
using apache::thrift::protocol::TJSONProtocol;
-static stdcxx::shared_ptr<OneOfEach> ooe;
+static std::shared_ptr<OneOfEach> ooe;
void testCaseSetup_1() {
ooe.reset(new OneOfEach);
@@ -67,7 +67,7 @@
"Expected:\n" << expected_result << "\nGotten:\n" << result);
}
-static stdcxx::shared_ptr<Nesting> n;
+static std::shared_ptr<Nesting> n;
void testCaseSetup_2() {
testCaseSetup_1();
@@ -107,7 +107,7 @@
"Expected:\n" << expected_result << "\nGotten:\n" << result);
}
-static stdcxx::shared_ptr<HolyMoley> hm;
+static std::shared_ptr<HolyMoley> hm;
void testCaseSetup_3() {
testCaseSetup_2();
@@ -185,8 +185,8 @@
BOOST_AUTO_TEST_CASE(test_json_proto_4) {
testCaseSetup_1();
- stdcxx::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- stdcxx::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
+ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
+ std::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
ooe->write(proto.get());
OneOfEach ooe2;
@@ -198,8 +198,8 @@
BOOST_AUTO_TEST_CASE(test_json_proto_5) {
testCaseSetup_3();
- stdcxx::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- stdcxx::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
+ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
+ std::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
hm->write(proto.get());
HolyMoley hm2;
@@ -236,8 +236,8 @@
}
BOOST_AUTO_TEST_CASE(test_json_proto_7) {
- stdcxx::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- stdcxx::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
+ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
+ std::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
Base64 base;
base.a = 123;
@@ -265,9 +265,9 @@
"\",3,1,2,3]}}";
const std::size_t bufSiz = strlen(json_string) * sizeof(char);
- stdcxx::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(
+ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(
(uint8_t*)(json_string), static_cast<uint32_t>(bufSiz)));
- stdcxx::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
+ std::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
OneOfEach ooe2;
@@ -294,9 +294,9 @@
"\",3,1,2,3]}}";
const char* expected_zomg_unicode = "\xe0\xb8\x81 \xf0\x9d\x94\xbe";
- stdcxx::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(
+ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(
(uint8_t*)(json_string), sizeof(json_string)));
- stdcxx::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
+ std::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
OneOfEach ooe2;
ooe2.read(proto.get());
@@ -315,9 +315,9 @@
":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2,3]},\"14\":{\"lst\":[\"i64"
"\",3,1,2,3]}}";
- stdcxx::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(
+ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(
(uint8_t*)(json_string), sizeof(json_string)));
- stdcxx::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
+ std::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
OneOfEach ooe2;
BOOST_CHECK_THROW(ooe2.read(proto.get()),
@@ -333,9 +333,9 @@
":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2,3]},\"14\":{\"lst\":[\"i64"
"\",3,1,2,3]}}";
- stdcxx::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(
+ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(
(uint8_t*)(json_string), sizeof(json_string)));
- stdcxx::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
+ std::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
OneOfEach ooe2;
BOOST_CHECK_THROW(ooe2.read(proto.get()),
diff --git a/lib/cpp/test/Makefile.am b/lib/cpp/test/Makefile.am
index 4b9f77d..5bb9eb7 100755
--- a/lib/cpp/test/Makefile.am
+++ b/lib/cpp/test/Makefile.am
@@ -135,12 +135,6 @@
TServerTransportTest.cpp \
TTransportCheckThrow.h
-if !WITH_BOOSTTHREADS
-UnitTests_SOURCES += \
- concurrency/MutexTest.cpp \
- concurrency/RWMutexStarveTest.cpp
-endif
-
UnitTests_LDADD = \
libtestgencpp.la \
$(BOOST_TEST_LDADD) \
diff --git a/lib/cpp/test/OneWayHTTPTest.cpp b/lib/cpp/test/OneWayHTTPTest.cpp
index 3fe63b6..55d919b 100644
--- a/lib/cpp/test/OneWayHTTPTest.cpp
+++ b/lib/cpp/test/OneWayHTTPTest.cpp
@@ -30,7 +30,7 @@
#include <thrift/transport/THttpClient.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TSocket.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/transport/TBufferTransports.h>
#include "gen-cpp/OneWayService.h"
@@ -54,7 +54,7 @@
using apache::thrift::transport::TServerSocket;
using apache::thrift::transport::TSocket;
using apache::thrift::transport::TTransportException;
-using apache::thrift::stdcxx::shared_ptr;
+using std::shared_ptr;
using std::cout;
using std::cerr;
using std::endl;
@@ -66,14 +66,14 @@
class OneWayServiceHandler : public onewaytest::OneWayServiceIf {
public:
- OneWayServiceHandler() {}
+ OneWayServiceHandler() = default;
void roundTripRPC() override {
#ifdef ENABLE_STDERR_LOGGING
cerr << "roundTripRPC()" << endl;
#endif
}
- void oneWayRPC() {
+ void oneWayRPC() override {
#ifdef ENABLE_STDERR_LOGGING
cerr << "oneWayRPC()" << std::endl ;
#endif
@@ -82,13 +82,13 @@
class OneWayServiceCloneFactory : virtual public onewaytest::OneWayServiceIfFactory {
public:
- virtual ~OneWayServiceCloneFactory() {}
- virtual onewaytest::OneWayServiceIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo)
+ ~OneWayServiceCloneFactory() override = default;
+ onewaytest::OneWayServiceIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) override
{
(void)connInfo ;
return new OneWayServiceHandler;
}
- virtual void releaseHandler( onewaytest::OneWayServiceIf* handler) {
+ void releaseHandler( onewaytest::OneWayServiceIf* handler) override {
delete handler;
}
};
@@ -96,7 +96,7 @@
class RPC0ThreadClass {
public:
RPC0ThreadClass(TThreadedServer& server) : server_(server) { } // Constructor
-~RPC0ThreadClass() { } // Destructor
+~RPC0ThreadClass() = default; // Destructor
void Run() {
server_.serve() ;
@@ -112,21 +112,21 @@
class TServerReadyEventHandler : public TServerEventHandler, public Monitor {
public:
TServerReadyEventHandler() : isListening_(false), accepted_(0) {}
- virtual ~TServerReadyEventHandler() {}
- virtual void preServe() {
+ ~TServerReadyEventHandler() override = default;
+ void preServe() override {
Synchronized sync(*this);
isListening_ = true;
notify();
}
- virtual void* createContext(shared_ptr<TProtocol> input,
- shared_ptr<TProtocol> output) {
+ void* createContext(shared_ptr<TProtocol> input,
+ shared_ptr<TProtocol> output) override {
Synchronized sync(*this);
++accepted_;
notify();
(void)input;
(void)output;
- return NULL;
+ return nullptr;
}
bool isListening() const { return isListening_; }
uint64_t acceptedCount() const { return accepted_; }
@@ -138,13 +138,13 @@
class TBlockableBufferedTransport : public TBufferedTransport {
public:
- TBlockableBufferedTransport(stdcxx::shared_ptr<TTransport> transport)
+ TBlockableBufferedTransport(std::shared_ptr<TTransport> transport)
: TBufferedTransport(transport, 10240),
blocked_(false) {
}
uint32_t write_buffer_length() {
- uint32_t have_bytes = static_cast<uint32_t>(wBase_ - wBuf_.get());
+ auto have_bytes = static_cast<uint32_t>(wBase_ - wBuf_.get());
return have_bytes ;
}
@@ -176,14 +176,14 @@
BOOST_AUTO_TEST_CASE( JSON_BufferedHTTP )
{
- stdcxx::shared_ptr<TServerSocket> ss = stdcxx::make_shared<TServerSocket>(0) ;
+ std::shared_ptr<TServerSocket> ss = std::make_shared<TServerSocket>(0) ;
TThreadedServer server(
- stdcxx::make_shared<onewaytest::OneWayServiceProcessorFactory>(stdcxx::make_shared<OneWayServiceCloneFactory>()),
+ std::make_shared<onewaytest::OneWayServiceProcessorFactory>(std::make_shared<OneWayServiceCloneFactory>()),
ss, //port
- stdcxx::make_shared<THttpServerTransportFactory>(),
- stdcxx::make_shared<TJSONProtocolFactory>());
+ std::make_shared<THttpServerTransportFactory>(),
+ std::make_shared<TJSONProtocolFactory>());
- stdcxx::shared_ptr<TServerReadyEventHandler> pEventHandler(new TServerReadyEventHandler) ;
+ std::shared_ptr<TServerReadyEventHandler> pEventHandler(new TServerReadyEventHandler) ;
server.setServerEventHandler(pEventHandler);
#ifdef ENABLE_STDERR_LOGGING
@@ -205,11 +205,11 @@
#endif
{
- stdcxx::shared_ptr<TSocket> socket(new TSocket("localhost", port));
+ std::shared_ptr<TSocket> socket(new TSocket("localhost", port));
socket->setRecvTimeout(10000) ; // 1000msec should be enough
- stdcxx::shared_ptr<TBlockableBufferedTransport> blockable_transport(new TBlockableBufferedTransport(socket));
- stdcxx::shared_ptr<TTransport> transport(new THttpClient(blockable_transport, "localhost", "/service"));
- stdcxx::shared_ptr<TProtocol> protocol(new TJSONProtocol(transport));
+ std::shared_ptr<TBlockableBufferedTransport> blockable_transport(new TBlockableBufferedTransport(socket));
+ std::shared_ptr<TTransport> transport(new THttpClient(blockable_transport, "localhost", "/service"));
+ std::shared_ptr<TProtocol> protocol(new TJSONProtocol(transport));
onewaytest::OneWayServiceClient client(protocol);
@@ -227,7 +227,7 @@
blockable_transport->flush() ;
try {
client.recv_roundTripRPC() ;
- } catch (TTransportException e) {
+ } catch (const TTransportException &e) {
BOOST_ERROR( "we should not get a transport exception -- this means we failed: " + std::string(e.what()) ) ;
}
transport->close();
diff --git a/lib/cpp/test/OneWayTest.thrift b/lib/cpp/test/OneWayTest.thrift
index 127e9ff..102cf26 100644
--- a/lib/cpp/test/OneWayTest.thrift
+++ b/lib/cpp/test/OneWayTest.thrift
@@ -34,7 +34,6 @@
namespace go onewaytest
namespace php OneWayTest
namespace delphi Onewaytest
-namespace cocoa OneWayTest
namespace lua OneWayTest
namespace xsd test (uri = 'http://thrift.apache.org/ns/OneWayTest')
namespace netcore ThriftAsync.OneWayTest
diff --git a/lib/cpp/test/OpenSSLManualInitTest.cpp b/lib/cpp/test/OpenSSLManualInitTest.cpp
index a30b303..a751806 100644
--- a/lib/cpp/test/OpenSSLManualInitTest.cpp
+++ b/lib/cpp/test/OpenSSLManualInitTest.cpp
@@ -62,7 +62,7 @@
// uninitialized. It might also fail on very old versions of
// OpenSSL...
const EVP_MD* md = EVP_get_digestbyname("SHA256");
- BOOST_CHECK(md != NULL);
+ BOOST_CHECK(md != nullptr);
openssl_cleanup();
}
diff --git a/lib/cpp/test/OptionalRequiredTest.cpp b/lib/cpp/test/OptionalRequiredTest.cpp
index 55fe249..4c43546 100644
--- a/lib/cpp/test/OptionalRequiredTest.cpp
+++ b/lib/cpp/test/OptionalRequiredTest.cpp
@@ -40,7 +40,7 @@
void trywrite(const Struct& s, bool should_work) {
bool worked;
try {
- TBinaryProtocol protocol(stdcxx::shared_ptr<TTransport>(new TMemoryBuffer));
+ TBinaryProtocol protocol(std::shared_ptr<TTransport>(new TMemoryBuffer));
s.write(&protocol);
worked = true;
} catch (TProtocolException & ex) {
@@ -52,7 +52,7 @@
template <typename Struct1, typename Struct2>
void write_to_read(const Struct1& w, Struct2& r) {
- TBinaryProtocol protocol(stdcxx::shared_ptr<TTransport>(new TMemoryBuffer));
+ TBinaryProtocol protocol(std::shared_ptr<TTransport>(new TMemoryBuffer));
w.write(&protocol);
r.read(&protocol);
}
@@ -303,7 +303,7 @@
o1.im_big.push_back(mymap);
BOOST_CHECK(o1 == o2);
- TBinaryProtocol protocol(stdcxx::shared_ptr<TTransport>(new TMemoryBuffer));
+ TBinaryProtocol protocol(std::shared_ptr<TTransport>(new TMemoryBuffer));
o1.write(&protocol);
o1.im_big.push_back(mymap);
diff --git a/lib/cpp/test/RecursiveTest.cpp b/lib/cpp/test/RecursiveTest.cpp
index ce5569b..ab2e46d 100644
--- a/lib/cpp/test/RecursiveTest.cpp
+++ b/lib/cpp/test/RecursiveTest.cpp
@@ -23,7 +23,7 @@
#include "gen-cpp/Recursive_types.h"
#include <thrift/protocol/TBinaryProtocol.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/transport/TBufferTransports.h>
#define BOOST_TEST_MODULE RecursiveTest
@@ -31,7 +31,7 @@
using apache::thrift::transport::TMemoryBuffer;
using apache::thrift::protocol::TBinaryProtocol;
-using apache::thrift::stdcxx::shared_ptr;
+using std::shared_ptr;
BOOST_AUTO_TEST_CASE(test_recursive_1) {
shared_ptr<TMemoryBuffer> buf(new TMemoryBuffer());
@@ -60,8 +60,8 @@
RecList resultlist;
resultlist.read(prot.get());
- BOOST_CHECK(resultlist.nextitem != NULL);
- BOOST_CHECK(resultlist.nextitem->nextitem == NULL);
+ BOOST_CHECK(resultlist.nextitem != nullptr);
+ BOOST_CHECK(resultlist.nextitem->nextitem == nullptr);
}
BOOST_AUTO_TEST_CASE(test_recursive_3) {
@@ -75,8 +75,8 @@
c.write(prot.get());
c.read(prot.get());
- BOOST_CHECK(c.other != NULL);
- BOOST_CHECK(c.other->other.other == NULL);
+ BOOST_CHECK(c.other != nullptr);
+ BOOST_CHECK(c.other->other.other == nullptr);
}
BOOST_AUTO_TEST_CASE(test_recursive_4) {
diff --git a/lib/cpp/test/SecurityTest.cpp b/lib/cpp/test/SecurityTest.cpp
index 51ee427..982a4f3 100644
--- a/lib/cpp/test/SecurityTest.cpp
+++ b/lib/cpp/test/SecurityTest.cpp
@@ -23,7 +23,7 @@
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <boost/thread.hpp>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/transport/TSSLServerSocket.h>
#include <thrift/transport/TSSLSocket.h>
#include <thrift/transport/TTransport.h>
@@ -40,8 +40,8 @@
using apache::thrift::transport::TTransportException;
using apache::thrift::transport::TTransportFactory;
-using apache::thrift::stdcxx::bind;
-using apache::thrift::stdcxx::shared_ptr;
+using std::bind;
+using std::shared_ptr;
boost::filesystem::path keyDir;
boost::filesystem::path certFile(const std::string& filename)
diff --git a/lib/cpp/test/SpecializationTest.cpp b/lib/cpp/test/SpecializationTest.cpp
index a060b4f..008837d 100644
--- a/lib/cpp/test/SpecializationTest.cpp
+++ b/lib/cpp/test/SpecializationTest.cpp
@@ -82,8 +82,8 @@
stage2.back().message = "nevermore";
hm.bonks["poe"] = stage2;
- apache::thrift::stdcxx::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
- apache::thrift::stdcxx::shared_ptr<TProtocol> proto(new MyProtocol(buffer));
+ std::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
+ std::shared_ptr<TProtocol> proto(new MyProtocol(buffer));
ooe.write(proto.get());
OneOfEach ooe2;
diff --git a/lib/cpp/test/TBufferBaseTest.cpp b/lib/cpp/test/TBufferBaseTest.cpp
index 4201ddb..7203f82 100644
--- a/lib/cpp/test/TBufferBaseTest.cpp
+++ b/lib/cpp/test/TBufferBaseTest.cpp
@@ -21,9 +21,9 @@
#include <boost/test/auto_unit_test.hpp>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TShortReadTransport.h>
-#include <thrift/stdcxx.h>
+#include <memory>
-using apache::thrift::stdcxx::shared_ptr;
+using std::shared_ptr;
using apache::thrift::transport::TMemoryBuffer;
using apache::thrift::transport::TBufferedTransport;
using apache::thrift::transport::TFramedTransport;
@@ -165,8 +165,8 @@
// Repeatability. Kind of.
std::srand(42);
- for (size_t i = 0; i < (sizeof(data)/sizeof(data[0])); ++i) {
- data[i] = (uint8_t)rand();
+ for (unsigned char & i : data) {
+ i = (uint8_t)rand();
}
data_str.assign((char*)data, sizeof(data));
@@ -178,14 +178,14 @@
BOOST_AUTO_TEST_CASE( test_MemoryBuffer_Write_GetBuffer ) {
init_data();
- for (int d1 = 0; d1 < 3; d1++) {
+ for (auto & d1 : dist) {
TMemoryBuffer buffer(16);
int offset = 0;
int index = 0;
while (offset < 1<<15) {
- buffer.write(&data[offset], dist[d1][index]);
- offset += dist[d1][index];
+ buffer.write(&data[offset], d1[index]);
+ offset += d1[index];
index++;
}
@@ -197,8 +197,8 @@
BOOST_AUTO_TEST_CASE( test_MemoryBuffer_Write_Read ) {
init_data();
- for (int d1 = 0; d1 < 3; d1++) {
- for (int d2 = 0; d2 < 3; d2++) {
+ for (auto & d1 : dist) {
+ for (auto & d2 : dist) {
TMemoryBuffer buffer(16);
uint8_t data_out[1<<15];
int offset;
@@ -207,17 +207,17 @@
offset = 0;
index = 0;
while (offset < 1<<15) {
- buffer.write(&data[offset], dist[d1][index]);
- offset += dist[d1][index];
+ buffer.write(&data[offset], d1[index]);
+ offset += d1[index];
index++;
}
offset = 0;
index = 0;
while (offset < 1<<15) {
- unsigned int got = buffer.read(&data_out[offset], dist[d2][index]);
- BOOST_CHECK_EQUAL(got, dist[d2][index]);
- offset += dist[d2][index];
+ unsigned int got = buffer.read(&data_out[offset], d2[index]);
+ BOOST_CHECK_EQUAL(got, d2[index]);
+ offset += d2[index];
index++;
}
@@ -229,8 +229,8 @@
BOOST_AUTO_TEST_CASE( test_MemoryBuffer_Write_ReadString ) {
init_data();
- for (int d1 = 0; d1 < 3; d1++) {
- for (int d2 = 0; d2 < 3; d2++) {
+ for (auto & d1 : dist) {
+ for (auto & d2 : dist) {
TMemoryBuffer buffer(16);
string output;
int offset;
@@ -239,17 +239,17 @@
offset = 0;
index = 0;
while (offset < 1<<15) {
- buffer.write(&data[offset], dist[d1][index]);
- offset += dist[d1][index];
+ buffer.write(&data[offset], d1[index]);
+ offset += d1[index];
index++;
}
offset = 0;
index = 0;
while (offset < 1<<15) {
- unsigned int got = buffer.readAppendToString(output, dist[d2][index]);
- BOOST_CHECK_EQUAL(got, dist[d2][index]);
- offset += dist[d2][index];
+ unsigned int got = buffer.readAppendToString(output, d2[index]);
+ BOOST_CHECK_EQUAL(got, d2[index]);
+ offset += d2[index];
index++;
}
@@ -263,8 +263,8 @@
// Do shorter writes and reads so we don't align to power-of-two boundaries.
- for (int d1 = 0; d1 < 3; d1++) {
- for (int d2 = 0; d2 < 3; d2++) {
+ for (auto & d1 : dist) {
+ for (auto & d2 : dist) {
TMemoryBuffer buffer(16);
uint8_t data_out[1<<15];
int offset;
@@ -274,16 +274,16 @@
offset = 0;
index = 0;
while (offset < (1<<15)-42) {
- buffer.write(&data[offset], dist[d1][index]);
- offset += dist[d1][index];
+ buffer.write(&data[offset], d1[index]);
+ offset += d1[index];
index++;
}
offset = 0;
index = 0;
while (offset < (1<<15)-42) {
- buffer.read(&data_out[offset], dist[d2][index]);
- offset += dist[d2][index];
+ buffer.read(&data_out[offset], d2[index]);
+ offset += d2[index];
index++;
}
@@ -303,8 +303,8 @@
// Pull the buffer out of the loop so its state gets worked harder.
TMemoryBuffer buffer(16);
- for (int d1 = 0; d1 < 3; d1++) {
- for (int d2 = 0; d2 < 3; d2++) {
+ for (auto & d1 : dist) {
+ for (auto & d2 : dist) {
uint8_t data_out[1<<15];
int offset;
int index;
@@ -313,16 +313,16 @@
offset = 0;
index = 0;
while (offset < (1<<15)-42) {
- buffer.write(&data[offset], dist[d1][index]);
- offset += dist[d1][index];
+ buffer.write(&data[offset], d1[index]);
+ offset += d1[index];
index++;
}
offset = 0;
index = 0;
while (offset < (1<<15)-42) {
- buffer.read(&data_out[offset], dist[d2][index]);
- offset += dist[d2][index];
+ buffer.read(&data_out[offset], d2[index]);
+ offset += d2[index];
index++;
}
@@ -341,8 +341,8 @@
// Do shorter writes and reads so we don't align to power-of-two boundaries.
// Pull the buffer out of the loop so its state gets worked harder.
- for (int d1 = 0; d1 < 3; d1++) {
- for (int d2 = 0; d2 < 3; d2++) {
+ for (auto & d1 : dist) {
+ for (auto & d2 : dist) {
TMemoryBuffer buffer(16);
uint8_t data_out[1<<13];
@@ -350,7 +350,7 @@
int write_index = 0;
unsigned int to_write = (1<<14)-42;
while (to_write > 0) {
- int write_amt = (std::min)(dist[d1][write_index], to_write);
+ int write_amt = (std::min)(d1[write_index], to_write);
buffer.write(&data[write_offset], write_amt);
write_offset += write_amt;
write_index++;
@@ -361,7 +361,7 @@
int read_index = 0;
unsigned int to_read = (1<<13)-42;
while (to_read > 0) {
- int read_amt = (std::min)(dist[d2][read_index], to_read);
+ int read_amt = (std::min)(d2[read_index], to_read);
int got = buffer.read(&data_out[read_offset], read_amt);
BOOST_CHECK_EQUAL(got, read_amt);
read_offset += read_amt;
@@ -375,7 +375,7 @@
int second_index = write_index-1;
unsigned int to_second = (1<<14)+42;
while (to_second > 0) {
- int second_amt = (std::min)(dist[d1][second_index], to_second);
+ int second_amt = (std::min)(d1[second_index], to_second);
//printf("%d\n", second_amt);
buffer.write(&data[second_offset], second_amt);
second_offset += second_amt;
@@ -399,17 +399,16 @@
1<<14, 1<<17,
};
- for (size_t i = 0; i < sizeof (sizes) / sizeof (sizes[0]); i++) {
- int size = sizes[i];
- for (int d1 = 0; d1 < 3; d1++) {
+ for (int size : sizes) {
+ for (auto & d1 : dist) {
shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(16));
TBufferedTransport trans(buffer, size);
int offset = 0;
int index = 0;
while (offset < 1<<15) {
- trans.write(&data[offset], dist[d1][index]);
- offset += dist[d1][index];
+ trans.write(&data[offset], d1[index]);
+ offset += d1[index];
index++;
}
trans.flush();
@@ -430,9 +429,8 @@
1<<14, 1<<17,
};
- for (size_t i = 0; i < sizeof (sizes) / sizeof (sizes[0]); i++) {
- int size = sizes[i];
- for (int d1 = 0; d1 < 3; d1++) {
+ for (int size : sizes) {
+ for (auto & d1 : dist) {
shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(data, sizeof(data)));
TBufferedTransport trans(buffer, size);
uint8_t data_out[1<<15];
@@ -443,8 +441,8 @@
// Note: this doesn't work with "read" because TBufferedTransport
// doesn't try loop over reads, so we get short reads. We don't
// check the return value, so that messes us up.
- trans.readAll(&data_out[offset], dist[d1][index]);
- offset += dist[d1][index];
+ trans.readAll(&data_out[offset], d1[index]);
+ offset += d1[index];
index++;
}
@@ -463,9 +461,8 @@
1<<14, 1<<17,
};
- for (size_t i = 0; i < sizeof (sizes) / sizeof (sizes[0]); i++) {
- int size = sizes[i];
- for (int d1 = 0; d1 < 3; d1++) {
+ for (int size : sizes) {
+ for (auto & d1 : dist) {
shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(data, sizeof(data)));
shared_ptr<TShortReadTransport> tshort(new TShortReadTransport(buffer, 0.125));
TBufferedTransport trans(buffer, size);
@@ -477,8 +474,8 @@
// Note: this doesn't work with "read" because TBufferedTransport
// doesn't try loop over reads, so we get short reads. We don't
// check the return value, so that messes us up.
- trans.readAll(&data_out[offset], dist[d1][index]);
- offset += dist[d1][index];
+ trans.readAll(&data_out[offset], d1[index]);
+ offset += d1[index];
index++;
}
@@ -497,17 +494,16 @@
1<<14, 1<<17,
};
- for (size_t i = 0; i < sizeof (sizes) / sizeof (sizes[0]); i++) {
- int size = sizes[i];
- for (int d1 = 0; d1 < 3; d1++) {
+ for (int size : sizes) {
+ for (auto & d1 : dist) {
shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(16));
TFramedTransport trans(buffer, size);
int offset = 0;
int index = 0;
while (offset < 1<<15) {
- trans.write(&data[offset], dist[d1][index]);
- offset += dist[d1][index];
+ trans.write(&data[offset], d1[index]);
+ offset += d1[index];
index++;
}
trans.flush();
@@ -526,7 +522,7 @@
BOOST_AUTO_TEST_CASE( test_FramedTransport_Read ) {
init_data();
- for (int d1 = 0; d1 < 3; d1++) {
+ for (auto & d1 : dist) {
uint8_t data_out[1<<15];
shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
TFramedTransport trans(buffer);
@@ -539,8 +535,8 @@
int index = 0;
while (offset < 1<<15) {
// This should work with read because we have one huge frame.
- trans.read(&data_out[offset], dist[d1][index]);
- offset += dist[d1][index];
+ trans.read(&data_out[offset], d1[index]);
+ offset += d1[index];
index++;
}
@@ -560,11 +556,9 @@
int probs[] = { 1, 2, 4, 8, 16, 32, };
- for (size_t i = 0; i < sizeof (sizes) / sizeof (sizes[0]); i++) {
- int size = sizes[i];
- for (size_t j = 0; j < sizeof (probs) / sizeof (probs[0]); j++) {
- int prob = probs[j];
- for (int d1 = 0; d1 < 3; d1++) {
+ for (int size : sizes) {
+ for (int prob : probs) {
+ for (auto & d1 : dist) {
shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer(16));
TFramedTransport trans(buffer, size);
std::vector<uint8_t> data_out(1<<17, 0);
@@ -574,9 +568,9 @@
int write_index = 0;
int flush_size = 0;
while (write_offset < 1<<15) {
- trans.write(&data[write_offset], dist[d1][write_index]);
- write_offset += dist[d1][write_index];
- flush_size += dist[d1][write_index];
+ trans.write(&data[write_offset], d1[write_index]);
+ write_offset += d1[write_index];
+ flush_size += d1[write_index];
write_index++;
if (flush_size > 0 && rand()%prob == 0) {
flush_sizes.push_back(flush_size);
@@ -593,8 +587,7 @@
int read_offset = 0;
int read_index = 0;
- for (unsigned int k = 0; k < flush_sizes.size(); k++) {
- int fsize = flush_sizes[k];
+ for (int fsize : flush_sizes) {
// We are exploiting an implementation detail of TFramedTransport.
// The read buffer starts empty and it will never do more than one
// readFrame per read, so we should always get exactly one frame.
diff --git a/lib/cpp/test/TFileTransportTest.cpp b/lib/cpp/test/TFileTransportTest.cpp
index d0c26b3..21c1f3b 100644
--- a/lib/cpp/test/TFileTransportTest.cpp
+++ b/lib/cpp/test/TFileTransportTest.cpp
@@ -64,12 +64,12 @@
};
typedef std::list<FsyncCall> CallList;
- FsyncLog() {}
+ FsyncLog() = default;
void fsync(int fd) {
(void)fd;
FsyncCall call;
- THRIFT_GETTIMEOFDAY(&call.time, NULL);
+ THRIFT_GETTIMEOFDAY(&call.time, nullptr);
calls_.push_back(call);
}
@@ -123,7 +123,7 @@
if (path_) {
::unlink(path_);
delete[] path_;
- path_ = NULL;
+ path_ = nullptr;
}
}
@@ -195,9 +195,9 @@
struct timeval start;
struct timeval end;
- THRIFT_GETTIMEOFDAY(&start, NULL);
+ THRIFT_GETTIMEOFDAY(&start, nullptr);
delete transport;
- THRIFT_GETTIMEOFDAY(&end, NULL);
+ THRIFT_GETTIMEOFDAY(&end, nullptr);
int delta = time_diff(&start, &end);
@@ -264,7 +264,7 @@
delete transport;
// Stop logging new fsync() calls
- fsync_log = NULL;
+ fsync_log = nullptr;
// Examine the fsync() log
//
@@ -278,13 +278,13 @@
// Make sure TFileTransport called fsync at least once
BOOST_WARN_GE(calls->size(), static_cast<FsyncLog::CallList::size_type>(1));
- const struct timeval* prev_time = NULL;
- for (FsyncLog::CallList::const_iterator it = calls->begin(); it != calls->end(); ++it) {
+ const struct timeval* prev_time = nullptr;
+ for (const auto & call : *calls) {
if (prev_time) {
- int delta = time_diff(prev_time, &it->time);
+ int delta = time_diff(prev_time, &call.time);
BOOST_WARN( delta < max_allowed_delta );
}
- prev_time = &it->time;
+ prev_time = &call.time;
}
}
@@ -318,13 +318,13 @@
transport.write(buf, 1);
struct timeval start;
- THRIFT_GETTIMEOFDAY(&start, NULL);
+ THRIFT_GETTIMEOFDAY(&start, nullptr);
for (unsigned int n = 0; n < 10; ++n) {
transport.flush();
struct timeval now;
- THRIFT_GETTIMEOFDAY(&now, NULL);
+ THRIFT_GETTIMEOFDAY(&now, nullptr);
// Fail if at any point we've been running for longer than half a second.
// (With the buggy code, TFileTransport used to take 3 seconds per flush())
@@ -349,11 +349,11 @@
void parse_args(int argc, char* argv[]) {
struct option long_opts[]
- = {{"help", false, NULL, 'h'}, {"tmp-dir", true, NULL, 't'}, {NULL, 0, NULL, 0}};
+ = {{"help", false, nullptr, 'h'}, {"tmp-dir", true, nullptr, 't'}, {nullptr, 0, nullptr, 0}};
while (true) {
optopt = 1;
- int optchar = getopt_long(argc, argv, "ht:", long_opts, NULL);
+ int optchar = getopt_long(argc, argv, "ht:", long_opts, nullptr);
if (optchar == -1) {
break;
}
@@ -378,7 +378,7 @@
#ifdef BOOST_TEST_DYN_LINK
static int myArgc = 0;
-static char **myArgv = NULL;
+static char **myArgv = nullptr;
bool init_unit_test_suite() {
boost::unit_test::framework::master_test_suite().p_name.value = "TFileTransportTest";
diff --git a/lib/cpp/test/TMemoryBufferTest.cpp b/lib/cpp/test/TMemoryBufferTest.cpp
index d81b1d8..42f9711 100644
--- a/lib/cpp/test/TMemoryBufferTest.cpp
+++ b/lib/cpp/test/TMemoryBufferTest.cpp
@@ -22,7 +22,7 @@
#include <climits>
#include <vector>
#include <thrift/protocol/TBinaryProtocol.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/transport/TBufferTransports.h>
#include "gen-cpp/ThriftTest_types.h"
@@ -31,7 +31,7 @@
using apache::thrift::protocol::TBinaryProtocol;
using apache::thrift::transport::TMemoryBuffer;
using apache::thrift::transport::TTransportException;
-using apache::thrift::stdcxx::shared_ptr;
+using std::shared_ptr;
using std::cout;
using std::endl;
using std::string;
@@ -81,9 +81,9 @@
}
BOOST_AUTO_TEST_CASE(test_readAppendToString) {
- string* str1 = new string("abcd1234");
- TMemoryBuffer buf((uint8_t*)str1->data(),
- static_cast<uint32_t>(str1->length()),
+ string str1 = "abcd1234";
+ TMemoryBuffer buf((uint8_t*)str1.data(),
+ static_cast<uint32_t>(str1.length()),
TMemoryBuffer::COPY);
string str3 = "wxyz", str4 = "6789";
diff --git a/lib/cpp/test/TNonblockingSSLServerTest.cpp b/lib/cpp/test/TNonblockingSSLServerTest.cpp
index 3e9700f..dc40c12 100644
--- a/lib/cpp/test/TNonblockingSSLServerTest.cpp
+++ b/lib/cpp/test/TNonblockingSSLServerTest.cpp
@@ -19,8 +19,6 @@
#define BOOST_TEST_MODULE TNonblockingSSLServerTest
#include <boost/test/unit_test.hpp>
-#include <boost/smart_ptr.hpp>
-#include <boost/shared_ptr.hpp>
#include <boost/filesystem.hpp>
#include <boost/format.hpp>
@@ -41,17 +39,17 @@
using apache::thrift::transport::TSSLSocket;
struct Handler : public test::ParentServiceIf {
- void addString(const std::string& s) { strings_.push_back(s); }
- void getStrings(std::vector<std::string>& _return) { _return = strings_; }
+ void addString(const std::string& s) override { strings_.push_back(s); }
+ void getStrings(std::vector<std::string>& _return) override { _return = strings_; }
std::vector<std::string> strings_;
// dummy overrides not used in this test
- int32_t incrementGeneration() { return 0; }
- int32_t getGeneration() { return 0; }
- void getDataWait(std::string&, const int32_t) {}
- void onewayWait() {}
- void exceptionWait(const std::string&) {}
- void unexpectedExceptionWait(const std::string&) {}
+ int32_t incrementGeneration() override { return 0; }
+ int32_t getGeneration() override { return 0; }
+ void getDataWait(std::string&, const int32_t) override {}
+ void onewayWait() override {}
+ void exceptionWait(const std::string&) override {}
+ void unexpectedExceptionWait(const std::string&) override {}
};
boost::filesystem::path keyDir;
@@ -105,8 +103,8 @@
BOOST_GLOBAL_FIXTURE(GlobalFixtureSSL)
#endif
-stdcxx::shared_ptr<TSSLSocketFactory> createServerSocketFactory() {
- stdcxx::shared_ptr<TSSLSocketFactory> pServerSocketFactory;
+std::shared_ptr<TSSLSocketFactory> createServerSocketFactory() {
+ std::shared_ptr<TSSLSocketFactory> pServerSocketFactory;
pServerSocketFactory.reset(new TSSLSocketFactory());
pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
@@ -116,8 +114,8 @@
return pServerSocketFactory;
}
-stdcxx::shared_ptr<TSSLSocketFactory> createClientSocketFactory() {
- stdcxx::shared_ptr<TSSLSocketFactory> pClientSocketFactory;
+std::shared_ptr<TSSLSocketFactory> createClientSocketFactory() {
+ std::shared_ptr<TSSLSocketFactory> pClientSocketFactory;
pClientSocketFactory.reset(new TSSLSocketFactory());
pClientSocketFactory->authenticate(true);
@@ -133,7 +131,7 @@
public:
ListenEventHandler(Mutex* mutex) : listenMonitor_(mutex), ready_(false) {}
- void preServe() /* override */ {
+ void preServe() override /* override */ {
Guard g(listenMonitor_.mutex());
ready_ = true;
listenMonitor_.notify();
@@ -145,19 +143,19 @@
struct Runner : public apache::thrift::concurrency::Runnable {
int port;
- stdcxx::shared_ptr<event_base> userEventBase;
- stdcxx::shared_ptr<TProcessor> processor;
- stdcxx::shared_ptr<server::TNonblockingServer> server;
- stdcxx::shared_ptr<ListenEventHandler> listenHandler;
- stdcxx::shared_ptr<TSSLSocketFactory> pServerSocketFactory;
- stdcxx::shared_ptr<transport::TNonblockingSSLServerSocket> socket;
+ std::shared_ptr<event_base> userEventBase;
+ std::shared_ptr<TProcessor> processor;
+ std::shared_ptr<server::TNonblockingServer> server;
+ std::shared_ptr<ListenEventHandler> listenHandler;
+ std::shared_ptr<TSSLSocketFactory> pServerSocketFactory;
+ std::shared_ptr<transport::TNonblockingSSLServerSocket> socket;
Mutex mutex_;
- Runner() {
+ Runner():port(0) {
listenHandler.reset(new ListenEventHandler(&mutex_));
}
- virtual void run() {
+ void run() override {
// When binding to explicit port, allow retrying to workaround bind failures on ports in use
int retryCount = port ? 10 : 0;
pServerSocketFactory = createServerSocketFactory();
@@ -198,7 +196,7 @@
};
protected:
- Fixture() : processor(new test::ParentServiceProcessor(stdcxx::make_shared<Handler>())) {}
+ Fixture() : processor(new test::ParentServiceProcessor(std::make_shared<Handler>())) {}
~Fixture() {
if (server) {
@@ -214,18 +212,13 @@
}
int startServer(int port) {
- stdcxx::shared_ptr<Runner> runner(new Runner);
+ std::shared_ptr<Runner> runner(new Runner);
runner->port = port;
runner->processor = processor;
runner->userEventBase = userEventBase_;
- apache::thrift::stdcxx::scoped_ptr<apache::thrift::concurrency::ThreadFactory> threadFactory(
- new apache::thrift::concurrency::PlatformThreadFactory(
-#if !USE_BOOST_THREAD && !USE_STD_THREAD
- concurrency::PlatformThreadFactory::OTHER, concurrency::PlatformThreadFactory::NORMAL,
- 1,
-#endif
- false));
+ std::unique_ptr<apache::thrift::concurrency::ThreadFactory> threadFactory(
+ new apache::thrift::concurrency::ThreadFactory(false));
thread = threadFactory->newThread(runner);
thread->start();
runner->readyBarrier();
@@ -235,11 +228,11 @@
}
bool canCommunicate(int serverPort) {
- stdcxx::shared_ptr<TSSLSocketFactory> pClientSocketFactory = createClientSocketFactory();
- stdcxx::shared_ptr<TSSLSocket> socket = pClientSocketFactory->createSocket("localhost", serverPort);
+ std::shared_ptr<TSSLSocketFactory> pClientSocketFactory = createClientSocketFactory();
+ std::shared_ptr<TSSLSocket> socket = pClientSocketFactory->createSocket("localhost", serverPort);
socket->open();
- test::ParentServiceClient client(stdcxx::make_shared<protocol::TBinaryProtocol>(
- stdcxx::make_shared<transport::TFramedTransport>(socket)));
+ test::ParentServiceClient client(std::make_shared<protocol::TBinaryProtocol>(
+ std::make_shared<transport::TFramedTransport>(socket)));
client.addString("foo");
std::vector<std::string> strings;
client.getStrings(strings);
@@ -247,12 +240,12 @@
}
private:
- stdcxx::shared_ptr<event_base> userEventBase_;
- stdcxx::shared_ptr<test::ParentServiceProcessor> processor;
+ std::shared_ptr<event_base> userEventBase_;
+ std::shared_ptr<test::ParentServiceProcessor> processor;
protected:
- stdcxx::shared_ptr<server::TNonblockingServer> server;
+ std::shared_ptr<server::TNonblockingServer> server;
private:
- stdcxx::shared_ptr<apache::thrift::concurrency::Thread> thread;
+ std::shared_ptr<apache::thrift::concurrency::Thread> thread;
};
diff --git a/lib/cpp/test/TNonblockingServerTest.cpp b/lib/cpp/test/TNonblockingServerTest.cpp
index 63d8a04..f9aab4c 100644
--- a/lib/cpp/test/TNonblockingServerTest.cpp
+++ b/lib/cpp/test/TNonblockingServerTest.cpp
@@ -19,12 +19,12 @@
#define BOOST_TEST_MODULE TNonblockingServerTest
#include <boost/test/unit_test.hpp>
+#include <memory>
#include "thrift/concurrency/Monitor.h"
#include "thrift/concurrency/Thread.h"
#include "thrift/server/TNonblockingServer.h"
#include "thrift/transport/TNonblockingServerSocket.h"
-#include "thrift/stdcxx.h"
#include "gen-cpp/ParentService.h"
@@ -33,28 +33,28 @@
using apache::thrift::concurrency::Guard;
using apache::thrift::concurrency::Monitor;
using apache::thrift::concurrency::Mutex;
-using apache::thrift::concurrency::PlatformThreadFactory;
+using apache::thrift::concurrency::ThreadFactory;
using apache::thrift::concurrency::Runnable;
using apache::thrift::concurrency::Thread;
using apache::thrift::concurrency::ThreadFactory;
using apache::thrift::server::TServerEventHandler;
-using apache::thrift::stdcxx::make_shared;
-using apache::thrift::stdcxx::shared_ptr;
+using std::make_shared;
+using std::shared_ptr;
using namespace apache::thrift;
struct Handler : public test::ParentServiceIf {
- void addString(const std::string& s) { strings_.push_back(s); }
- void getStrings(std::vector<std::string>& _return) { _return = strings_; }
+ void addString(const std::string& s) override { strings_.push_back(s); }
+ void getStrings(std::vector<std::string>& _return) override { _return = strings_; }
std::vector<std::string> strings_;
// dummy overrides not used in this test
- int32_t incrementGeneration() { return 0; }
- int32_t getGeneration() { return 0; }
- void getDataWait(std::string&, const int32_t) {}
- void onewayWait() {}
- void exceptionWait(const std::string&) {}
- void unexpectedExceptionWait(const std::string&) {}
+ int32_t incrementGeneration() override { return 0; }
+ int32_t getGeneration() override { return 0; }
+ void getDataWait(std::string&, const int32_t) override {}
+ void onewayWait() override {}
+ void exceptionWait(const std::string&) override {}
+ void unexpectedExceptionWait(const std::string&) override {}
};
class Fixture {
@@ -63,7 +63,7 @@
public:
ListenEventHandler(Mutex* mutex) : listenMonitor_(mutex), ready_(false) {}
- void preServe() /* override */ {
+ void preServe() override /* override */ {
Guard g(listenMonitor_.mutex());
ready_ = true;
listenMonitor_.notify();
@@ -83,10 +83,11 @@
Mutex mutex_;
Runner() {
+ port = 0;
listenHandler.reset(new ListenEventHandler(&mutex_));
}
- virtual void run() {
+ void run() override {
// When binding to explicit port, allow retrying to workaround bind failures on ports in use
int retryCount = port ? 10 : 0;
startServer(retryCount);
@@ -147,12 +148,7 @@
runner->userEventBase = userEventBase_;
shared_ptr<ThreadFactory> threadFactory(
- new PlatformThreadFactory(
-#if !USE_BOOST_THREAD && !USE_STD_THREAD
- PlatformThreadFactory::OTHER, PlatformThreadFactory::NORMAL,
- 1,
-#endif
- false));
+ new ThreadFactory(false));
thread = threadFactory->newThread(runner);
thread->start();
runner->readyBarrier();
diff --git a/lib/cpp/test/TPipeInterruptTest.cpp b/lib/cpp/test/TPipeInterruptTest.cpp
index 232e4bb..2423f56 100644
--- a/lib/cpp/test/TPipeInterruptTest.cpp
+++ b/lib/cpp/test/TPipeInterruptTest.cpp
@@ -27,7 +27,7 @@
#include <boost/thread/thread.hpp>
#include <thrift/transport/TPipe.h>
#include <thrift/transport/TPipeServer.h>
-#include <thrift/stdcxx.h>
+#include <memory>
using apache::thrift::transport::TPipeServer;
using apache::thrift::transport::TPipe;
@@ -52,7 +52,7 @@
{
for (;;)
{
- stdcxx::shared_ptr<TTransport> temp = pipe->accept();
+ std::shared_ptr<TTransport> temp = pipe->accept();
}
}
catch (...) {/*just want to make sure nothing crashes*/ }
@@ -70,8 +70,8 @@
{
TPipeServer pipeServer("TPipeInterruptTest");
pipeServer.listen();
- boost::thread acceptThread(stdcxx::bind(acceptWorker, &pipeServer));
- boost::thread interruptThread(stdcxx::bind(interruptWorker, &pipeServer));
+ boost::thread acceptThread(std::bind(acceptWorker, &pipeServer));
+ boost::thread interruptThread(std::bind(interruptWorker, &pipeServer));
try
{
for (;;)
diff --git a/lib/cpp/test/TPipedTransportTest.cpp b/lib/cpp/test/TPipedTransportTest.cpp
index a3ce662..f3091a4 100644
--- a/lib/cpp/test/TPipedTransportTest.cpp
+++ b/lib/cpp/test/TPipedTransportTest.cpp
@@ -18,7 +18,7 @@
*/
#include <thrift/Thrift.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/transport/TBufferTransports.h>
@@ -31,9 +31,9 @@
using namespace apache::thrift;
BOOST_AUTO_TEST_CASE(test_read_write) {
- stdcxx::shared_ptr<TMemoryBuffer> underlying(new TMemoryBuffer);
- stdcxx::shared_ptr<TMemoryBuffer> pipe(new TMemoryBuffer);
- stdcxx::shared_ptr<TPipedTransport> trans(new TPipedTransport(underlying, pipe));
+ std::shared_ptr<TMemoryBuffer> underlying(new TMemoryBuffer);
+ std::shared_ptr<TMemoryBuffer> pipe(new TMemoryBuffer);
+ std::shared_ptr<TPipedTransport> trans(new TPipedTransport(underlying, pipe));
uint8_t buffer[4];
diff --git a/lib/cpp/test/TSSLSocketInterruptTest.cpp b/lib/cpp/test/TSSLSocketInterruptTest.cpp
index 85f6c39..33f686c 100644
--- a/lib/cpp/test/TSSLSocketInterruptTest.cpp
+++ b/lib/cpp/test/TSSLSocketInterruptTest.cpp
@@ -24,7 +24,7 @@
#include <boost/thread/thread.hpp>
#include <boost/filesystem.hpp>
#include <boost/format.hpp>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/transport/TSSLSocket.h>
#include <thrift/transport/TSSLServerSocket.h>
#ifdef __linux__
@@ -37,8 +37,8 @@
using apache::thrift::transport::TTransportException;
using apache::thrift::transport::TSSLSocketFactory;
-using apache::thrift::stdcxx::static_pointer_cast;
-using apache::thrift::stdcxx::shared_ptr;
+using std::static_pointer_cast;
+using std::shared_ptr;
BOOST_AUTO_TEST_SUITE(TSSLSocketInterruptTest)
@@ -146,7 +146,7 @@
shared_ptr<TSSLSocket> clientSock = pClientSocketFactory->createSocket("localhost", port);
clientSock->open();
shared_ptr<TTransport> accepted = sock1.accept();
- boost::thread readThread(apache::thrift::stdcxx::bind(readerWorkerMustThrow, accepted));
+ boost::thread readThread(std::bind(readerWorkerMustThrow, accepted));
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
// readThread is practically guaranteed to be blocking now
sock1.interruptChildren();
@@ -166,7 +166,7 @@
shared_ptr<TSSLSocket> clientSock = pClientSocketFactory->createSocket("localhost", port);
clientSock->open();
shared_ptr<TTransport> accepted = sock1.accept();
- boost::thread readThread(apache::thrift::stdcxx::bind(readerWorkerMustThrow, accepted));
+ boost::thread readThread(std::bind(readerWorkerMustThrow, accepted));
clientSock->write((const uint8_t*)"0", 1);
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
// readThread is practically guaranteed to be blocking now
@@ -189,7 +189,7 @@
clientSock->open();
shared_ptr<TTransport> accepted = sock1.accept();
static_pointer_cast<TSSLSocket>(accepted)->setRecvTimeout(1000);
- boost::thread readThread(apache::thrift::stdcxx::bind(readerWorker, accepted, 0));
+ boost::thread readThread(std::bind(readerWorker, accepted, 0));
clientSock->write((const uint8_t*)"0", 1);
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
// readThread is practically guaranteed to be blocking here
@@ -241,7 +241,7 @@
shared_ptr<TSSLSocket> clientSock = pClientSocketFactory->createSocket("localhost", port);
clientSock->open();
shared_ptr<TTransport> accepted = sock1.accept();
- boost::thread peekThread(apache::thrift::stdcxx::bind(peekerWorkerInterrupt, accepted));
+ boost::thread peekThread(std::bind(peekerWorkerInterrupt, accepted));
clientSock->write((const uint8_t*)"0", 1);
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
// peekThread is practically guaranteed to be blocking now
@@ -264,7 +264,7 @@
clientSock->open();
shared_ptr<TTransport> accepted = sock1.accept();
static_pointer_cast<TSSLSocket>(accepted)->setRecvTimeout(1000);
- boost::thread peekThread(apache::thrift::stdcxx::bind(peekerWorker, accepted, false));
+ boost::thread peekThread(std::bind(peekerWorker, accepted, false));
clientSock->write((const uint8_t*)"0", 1);
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
// peekThread is practically guaranteed to be blocking now
diff --git a/lib/cpp/test/TServerIntegrationTest.cpp b/lib/cpp/test/TServerIntegrationTest.cpp
index 5f7b2e8..b88c35b 100644
--- a/lib/cpp/test/TServerIntegrationTest.cpp
+++ b/lib/cpp/test/TServerIntegrationTest.cpp
@@ -18,8 +18,8 @@
*/
#define BOOST_TEST_MODULE TServerIntegrationTest
+#include <atomic>
#include <boost/test/auto_unit_test.hpp>
-#include <boost/atomic.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/foreach.hpp>
#include <boost/format.hpp>
@@ -27,7 +27,7 @@
#include <thrift/server/TSimpleServer.h>
#include <thrift/server/TThreadPoolServer.h>
#include <thrift/server/TThreadedServer.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TSocket.h>
@@ -55,9 +55,9 @@
using apache::thrift::server::TSimpleServer;
using apache::thrift::server::TThreadPoolServer;
using apache::thrift::server::TThreadedServer;
-using apache::thrift::stdcxx::dynamic_pointer_cast;
-using apache::thrift::stdcxx::make_shared;
-using apache::thrift::stdcxx::shared_ptr;
+using std::dynamic_pointer_cast;
+using std::make_shared;
+using std::shared_ptr;
using apache::thrift::test::ParentServiceClient;
using apache::thrift::test::ParentServiceIf;
using apache::thrift::test::ParentServiceIfFactory;
@@ -74,21 +74,21 @@
class TServerReadyEventHandler : public TServerEventHandler, public Monitor {
public:
TServerReadyEventHandler() : isListening_(false), accepted_(0) {}
- virtual ~TServerReadyEventHandler() {}
- virtual void preServe() {
+ ~TServerReadyEventHandler() override = default;
+ void preServe() override {
Synchronized sync(*this);
isListening_ = true;
notify();
}
- virtual void* createContext(shared_ptr<TProtocol> input,
- shared_ptr<TProtocol> output) {
+ void* createContext(shared_ptr<TProtocol> input,
+ shared_ptr<TProtocol> output) override {
Synchronized sync(*this);
++accepted_;
notify();
(void)input;
(void)output;
- return NULL;
+ return nullptr;
}
bool isListening() const { return isListening_; }
uint64_t acceptedCount() const { return accepted_; }
@@ -105,36 +105,36 @@
public:
ParentHandler() : generation_(0) {}
- int32_t incrementGeneration() {
+ int32_t incrementGeneration() override {
Guard g(mutex_);
return ++generation_;
}
- int32_t getGeneration() {
+ int32_t getGeneration() override {
Guard g(mutex_);
return generation_;
}
- void addString(const std::string& s) {
+ void addString(const std::string& s) override {
Guard g(mutex_);
strings_.push_back(s);
}
- void getStrings(std::vector<std::string>& _return) {
+ void getStrings(std::vector<std::string>& _return) override {
Guard g(mutex_);
_return = strings_;
}
- void getDataWait(std::string& _return, const int32_t length) {
+ void getDataWait(std::string& _return, const int32_t length) override {
THRIFT_UNUSED_VARIABLE(_return);
THRIFT_UNUSED_VARIABLE(length);
}
- void onewayWait() {}
+ void onewayWait() override {}
- void exceptionWait(const std::string& message) { THRIFT_UNUSED_VARIABLE(message); }
+ void exceptionWait(const std::string& message) override { THRIFT_UNUSED_VARIABLE(message); }
- void unexpectedExceptionWait(const std::string& message) { THRIFT_UNUSED_VARIABLE(message); }
+ void unexpectedExceptionWait(const std::string& message) override { THRIFT_UNUSED_VARIABLE(message); }
protected:
Mutex mutex_;
@@ -177,7 +177,7 @@
}
void startServer() {
- pServerThread.reset(new boost::thread(apache::thrift::stdcxx::bind(&TServerType::serve, pServer.get())));
+ pServerThread.reset(new boost::thread(std::bind(&TServerType::serve, pServer.get())));
// block until listen() completes so clients will be able to connect
Synchronized sync(*(pEventHandler.get()));
@@ -235,7 +235,7 @@
pClientSock->open();
client.incrementGeneration();
holdThreads.push_back(shared_ptr<boost::thread>(
- new boost::thread(apache::thrift::stdcxx::bind(&TServerIntegrationTestFixture::delayClose,
+ new boost::thread(std::bind(&TServerIntegrationTestFixture::delayClose,
this,
pClientSock,
milliseconds(10 * numToMake)))));
@@ -264,7 +264,7 @@
* \returns the server port number
*/
int getServerPort() {
- TServerSocket* pSock = dynamic_cast<TServerSocket*>(pServer->getServerTransport().get());
+ auto* pSock = dynamic_cast<TServerSocket*>(pServer->getServerTransport().get());
if (!pSock) { throw std::logic_error("how come?"); }
return pSock->getPort();
}
@@ -284,7 +284,7 @@
std::vector<shared_ptr<boost::thread> > holdThreads;
for (int64_t i = 0; i < numToMake; ++i) {
holdThreads.push_back(shared_ptr<boost::thread>(
- new boost::thread(apache::thrift::stdcxx::bind(&TServerIntegrationTestFixture::stressor, this))));
+ new boost::thread(std::bind(&TServerIntegrationTestFixture::stressor, this))));
}
boost::this_thread::sleep(duration);
@@ -310,10 +310,10 @@
shared_ptr<TProtocol> pProtocol(new TBinaryProtocol(pSocket));
ParentServiceClient client(pProtocol);
pSocket->open();
- bStressConnectionCount.fetch_add(1, boost::memory_order_relaxed);
+ bStressConnectionCount.fetch_add(1, std::memory_order_relaxed);
for (int i = 0; i < rand() % 1000; ++i) {
client.incrementGeneration();
- bStressRequestCount.fetch_add(1, boost::memory_order_relaxed);
+ bStressRequestCount.fetch_add(1, std::memory_order_relaxed);
}
}
}
@@ -321,9 +321,9 @@
shared_ptr<TServerType> pServer;
shared_ptr<TServerReadyEventHandler> pEventHandler;
shared_ptr<boost::thread> pServerThread;
- boost::atomic<bool> bStressDone;
- boost::atomic_int64_t bStressConnectionCount;
- boost::atomic_int64_t bStressRequestCount;
+ std::atomic<bool> bStressDone;
+ std::atomic<int64_t> bStressConnectionCount;
+ std::atomic<int64_t> bStressRequestCount;
};
template <class TServerType>
@@ -379,7 +379,7 @@
TServerIntegrationProcessorFactoryTestFixture<TThreadPoolServer>) {
pServer->getThreadManager()->threadFactory(
shared_ptr<apache::thrift::concurrency::ThreadFactory>(
- new apache::thrift::concurrency::PlatformThreadFactory));
+ new apache::thrift::concurrency::ThreadFactory));
pServer->getThreadManager()->start();
// thread factory has 4 threads as a default
@@ -394,7 +394,7 @@
TServerIntegrationProcessorTestFixture<TThreadPoolServer>) {
pServer->getThreadManager()->threadFactory(
shared_ptr<apache::thrift::concurrency::ThreadFactory>(
- new apache::thrift::concurrency::PlatformThreadFactory));
+ new apache::thrift::concurrency::ThreadFactory));
pServer->getThreadManager()->start();
// thread factory has 4 threads as a default
@@ -409,7 +409,7 @@
TServerIntegrationProcessorTestFixture<TThreadPoolServer>) {
pServer->getThreadManager()->threadFactory(
shared_ptr<apache::thrift::concurrency::ThreadFactory>(
- new apache::thrift::concurrency::PlatformThreadFactory));
+ new apache::thrift::concurrency::ThreadFactory));
pServer->getThreadManager()->start();
pServer->setConcurrentClientLimit(4);
@@ -420,7 +420,7 @@
TServerIntegrationProcessorTestFixture<TThreadPoolServer>) {
pServer->getThreadManager()->threadFactory(
shared_ptr<apache::thrift::concurrency::ThreadFactory>(
- new apache::thrift::concurrency::PlatformThreadFactory));
+ new apache::thrift::concurrency::ThreadFactory));
pServer->getThreadManager()->start();
stress(10, boost::posix_time::seconds(3));
@@ -479,11 +479,11 @@
// Ensure they have been accepted
blockUntilAccepted(2);
- boost::thread t1(apache::thrift::stdcxx::bind(&TServerIntegrationTestFixture::delayClose,
+ boost::thread t1(std::bind(&TServerIntegrationTestFixture::delayClose,
this,
pClientSock1,
milliseconds(250)));
- boost::thread t2(apache::thrift::stdcxx::bind(&TServerIntegrationTestFixture::delayClose,
+ boost::thread t2(std::bind(&TServerIntegrationTestFixture::delayClose,
this,
pClientSock2,
milliseconds(250)));
@@ -517,7 +517,7 @@
BOOST_CHECK_EQUAL(2, pServer->getConcurrentClientCount());
// a third client cannot connect until one of the other two closes
- boost::thread t2(apache::thrift::stdcxx::bind(&TServerIntegrationTestFixture::delayClose,
+ boost::thread t2(std::bind(&TServerIntegrationTestFixture::delayClose,
this,
pClientSock2,
milliseconds(250)));
diff --git a/lib/cpp/test/TServerSocketTest.cpp b/lib/cpp/test/TServerSocketTest.cpp
index a191147..bec6d47 100644
--- a/lib/cpp/test/TServerSocketTest.cpp
+++ b/lib/cpp/test/TServerSocketTest.cpp
@@ -20,7 +20,7 @@
#include <boost/test/auto_unit_test.hpp>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TServerSocket.h>
-#include <thrift/stdcxx.h>
+#include <memory>
#include "TTransportCheckThrow.h"
#include <iostream>
@@ -28,7 +28,7 @@
using apache::thrift::transport::TSocket;
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportException;
-using apache::thrift::stdcxx::shared_ptr;
+using std::shared_ptr;
BOOST_AUTO_TEST_SUITE(TServerSocketTest)
diff --git a/lib/cpp/test/TServerTransportTest.cpp b/lib/cpp/test/TServerTransportTest.cpp
index dc6aede..18a393e 100644
--- a/lib/cpp/test/TServerTransportTest.cpp
+++ b/lib/cpp/test/TServerTransportTest.cpp
@@ -20,12 +20,12 @@
#include <boost/test/auto_unit_test.hpp>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TServerTransport.h>
-#include <thrift/stdcxx.h>
+#include <memory>
using apache::thrift::transport::TServerTransport;
using apache::thrift::transport::TTransport;
using apache::thrift::transport::TTransportException;
-using apache::thrift::stdcxx::shared_ptr;
+using std::shared_ptr;
BOOST_AUTO_TEST_SUITE(TServerTransportTest)
@@ -34,12 +34,12 @@
class TestTServerTransport : public TServerTransport {
public:
TestTServerTransport() : valid_(true) {}
- void close() {}
+ void close() override {}
bool valid_;
protected:
- shared_ptr<TTransport> acceptImpl() {
- return valid_ ? shared_ptr<TestTTransport>(new TestTTransport)
+ shared_ptr<TTransport> acceptImpl() override {
+ return valid_ ? std::make_shared<TestTTransport>()
: shared_ptr<TestTTransport>();
}
};
diff --git a/lib/cpp/test/TSocketInterruptTest.cpp b/lib/cpp/test/TSocketInterruptTest.cpp
index 3a189cc..366242f 100644
--- a/lib/cpp/test/TSocketInterruptTest.cpp
+++ b/lib/cpp/test/TSocketInterruptTest.cpp
@@ -25,7 +25,7 @@
#include <boost/thread/thread.hpp>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TServerSocket.h>
-#include <thrift/stdcxx.h>
+#include <memory>
using apache::thrift::transport::TServerSocket;
using apache::thrift::transport::TSocket;
@@ -35,12 +35,12 @@
BOOST_AUTO_TEST_SUITE(TSocketInterruptTest)
-void readerWorker(stdcxx::shared_ptr<TTransport> tt, uint32_t expectedResult) {
+void readerWorker(std::shared_ptr<TTransport> tt, uint32_t expectedResult) {
uint8_t buf[4];
BOOST_CHECK_EQUAL(expectedResult, tt->read(buf, 4));
}
-void readerWorkerMustThrow(stdcxx::shared_ptr<TTransport> tt) {
+void readerWorkerMustThrow(std::shared_ptr<TTransport> tt) {
try {
uint8_t buf[4];
tt->read(buf, 4);
@@ -56,8 +56,8 @@
int port = sock1.getPort();
TSocket clientSock("localhost", port);
clientSock.open();
- stdcxx::shared_ptr<TTransport> accepted = sock1.accept();
- boost::thread readThread(stdcxx::bind(readerWorkerMustThrow, accepted));
+ std::shared_ptr<TTransport> accepted = sock1.accept();
+ boost::thread readThread(std::bind(readerWorkerMustThrow, accepted));
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
// readThread is practically guaranteed to be blocking now
sock1.interruptChildren();
@@ -75,8 +75,8 @@
int port = sock1.getPort();
TSocket clientSock("localhost", port);
clientSock.open();
- stdcxx::shared_ptr<TTransport> accepted = sock1.accept();
- boost::thread readThread(stdcxx::bind(readerWorker, accepted, 0));
+ std::shared_ptr<TTransport> accepted = sock1.accept();
+ boost::thread readThread(std::bind(readerWorker, accepted, 0));
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
// readThread is practically guaranteed to be blocking here
sock1.interruptChildren();
@@ -97,7 +97,7 @@
sock1.close();
}
-void peekerWorker(stdcxx::shared_ptr<TTransport> tt, bool expectedResult) {
+void peekerWorker(std::shared_ptr<TTransport> tt, bool expectedResult) {
BOOST_CHECK_EQUAL(expectedResult, tt->peek());
}
@@ -107,9 +107,9 @@
int port = sock1.getPort();
TSocket clientSock("localhost", port);
clientSock.open();
- stdcxx::shared_ptr<TTransport> accepted = sock1.accept();
+ std::shared_ptr<TTransport> accepted = sock1.accept();
// peek() will return false if child is interrupted
- boost::thread peekThread(stdcxx::bind(peekerWorker, accepted, false));
+ boost::thread peekThread(std::bind(peekerWorker, accepted, false));
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
// peekThread is practically guaranteed to be blocking now
sock1.interruptChildren();
@@ -127,9 +127,9 @@
int port = sock1.getPort();
TSocket clientSock("localhost", port);
clientSock.open();
- stdcxx::shared_ptr<TTransport> accepted = sock1.accept();
+ std::shared_ptr<TTransport> accepted = sock1.accept();
// peek() will return false when remote side is closed
- boost::thread peekThread(stdcxx::bind(peekerWorker, accepted, false));
+ boost::thread peekThread(std::bind(peekerWorker, accepted, false));
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
// peekThread is practically guaranteed to be blocking now
sock1.interruptChildren();
diff --git a/lib/cpp/test/TransportTest.cpp b/lib/cpp/test/TransportTest.cpp
index d6ab457..a890aa8 100644
--- a/lib/cpp/test/TransportTest.cpp
+++ b/lib/cpp/test/TransportTest.cpp
@@ -26,7 +26,6 @@
#endif
#include <sstream>
#include <fstream>
-#include <thrift/stdcxx.h>
#include <boost/mpl/list.hpp>
#include <boost/shared_array.hpp>
@@ -58,7 +57,7 @@
class SizeGenerator {
public:
- virtual ~SizeGenerator() {}
+ virtual ~SizeGenerator() = default;
virtual uint32_t nextSize() = 0;
virtual std::string describe() const = 0;
};
@@ -66,8 +65,8 @@
class ConstantSizeGenerator : public SizeGenerator {
public:
ConstantSizeGenerator(uint32_t value) : value_(value) {}
- uint32_t nextSize() { return value_; }
- std::string describe() const {
+ uint32_t nextSize() override { return value_; }
+ std::string describe() const override {
std::ostringstream desc;
desc << value_;
return desc.str();
@@ -82,9 +81,9 @@
RandomSizeGenerator(uint32_t min, uint32_t max)
: generator_(rng, boost::uniform_int<int>(min, max)) {}
- uint32_t nextSize() { return generator_(); }
+ uint32_t nextSize() override { return generator_(); }
- std::string describe() const {
+ std::string describe() const override {
std::ostringstream desc;
desc << "rand(" << getMin() << ", " << getMax() << ")";
return desc.str();
@@ -110,11 +109,11 @@
GenericSizeGenerator(uint32_t min, uint32_t max)
: generator_(new RandomSizeGenerator(min, max)) {}
- uint32_t nextSize() { return generator_->nextSize(); }
- std::string describe() const { return generator_->describe(); }
+ uint32_t nextSize() override { return generator_->nextSize(); }
+ std::string describe() const override { return generator_->describe(); }
private:
- stdcxx::shared_ptr<SizeGenerator> generator_;
+ std::shared_ptr<SizeGenerator> generator_;
};
/**************************************************************************
@@ -132,17 +131,17 @@
template <class Transport_>
class CoupledTransports {
public:
- virtual ~CoupledTransports() {}
+ virtual ~CoupledTransports() = default;
typedef Transport_ TransportType;
CoupledTransports() : in(), out() {}
- stdcxx::shared_ptr<Transport_> in;
- stdcxx::shared_ptr<Transport_> out;
+ std::shared_ptr<Transport_> in;
+ std::shared_ptr<Transport_> out;
private:
- CoupledTransports(const CoupledTransports&);
- CoupledTransports& operator=(const CoupledTransports&);
+ CoupledTransports(const CoupledTransports&) = delete;
+ CoupledTransports& operator=(const CoupledTransports&) = delete;
};
/**
@@ -155,7 +154,7 @@
out = buf;
}
- stdcxx::shared_ptr<TMemoryBuffer> buf;
+ std::shared_ptr<TMemoryBuffer> buf;
};
/**
@@ -283,7 +282,7 @@
out.reset(new TFileTransport(filename));
}
- ~CoupledFileTransports() { remove(filename.c_str()); }
+ ~CoupledFileTransports() override { remove(filename.c_str()); }
std::string filename;
};
@@ -341,11 +340,11 @@
**************************************************************************/
struct TriggerInfo {
- TriggerInfo(int seconds, const stdcxx::shared_ptr<TTransport>& transport, uint32_t writeLength)
- : timeoutSeconds(seconds), transport(transport), writeLength(writeLength), next(NULL) {}
+ TriggerInfo(int seconds, const std::shared_ptr<TTransport>& transport, uint32_t writeLength)
+ : timeoutSeconds(seconds), transport(transport), writeLength(writeLength), next(nullptr) {}
int timeoutSeconds;
- stdcxx::shared_ptr<TTransport> transport;
+ std::shared_ptr<TTransport> transport;
uint32_t writeLength;
TriggerInfo* next;
};
@@ -356,7 +355,7 @@
bool g_teardown = false;
void alarm_handler() {
- TriggerInfo* info = NULL;
+ TriggerInfo* info = nullptr;
{
apache::thrift::concurrency::Synchronized s(g_alarm_monitor);
// The alarm timed out, which almost certainly means we're stuck
@@ -367,7 +366,7 @@
// tools/test/runner only records stdout messages in the failure messages for
// boost tests. (boost prints its test info to stdout.)
printf("Timeout alarm expired; attempting to unblock transport\n");
- if (g_triggerInfo == NULL) {
+ if (g_triggerInfo == nullptr) {
printf(" trigger stack is empty!\n");
}
@@ -378,7 +377,7 @@
}
// Write some data to the transport to hopefully unblock it.
- uint8_t* buf = new uint8_t[info->writeLength];
+ auto* buf = new uint8_t[info->writeLength];
memset(buf, 'b', info->writeLength);
boost::scoped_array<uint8_t> array(buf);
info->transport->write(buf, info->writeLength);
@@ -396,7 +395,7 @@
if (g_teardown)
return;
// calculate timeout
- if (g_triggerInfo == NULL) {
+ if (g_triggerInfo == nullptr) {
timeout = 0;
} else {
timeout = g_triggerInfo->timeoutSeconds * 1000;
@@ -420,12 +419,12 @@
* to the end.)
*/
void add_trigger(unsigned int seconds,
- const stdcxx::shared_ptr<TTransport>& transport,
+ const std::shared_ptr<TTransport>& transport,
uint32_t write_len) {
- TriggerInfo* info = new TriggerInfo(seconds, transport, write_len);
+ auto* info = new TriggerInfo(seconds, transport, write_len);
{
apache::thrift::concurrency::Synchronized s(g_alarm_monitor);
- if (g_triggerInfo == NULL) {
+ if (g_triggerInfo == nullptr) {
// This is the first trigger.
// Set g_triggerInfo, and schedule the alarm
g_triggerInfo = info;
@@ -442,17 +441,17 @@
}
void clear_triggers() {
- TriggerInfo* info = NULL;
+ TriggerInfo* info = nullptr;
{
apache::thrift::concurrency::Synchronized s(g_alarm_monitor);
info = g_triggerInfo;
- g_triggerInfo = NULL;
+ g_triggerInfo = nullptr;
g_numTriggersFired = 0;
g_alarm_monitor.notify();
}
- while (info != NULL) {
+ while (info != nullptr) {
TriggerInfo* next = info->next;
delete info;
info = next;
@@ -460,7 +459,7 @@
}
void set_trigger(unsigned int seconds,
- const stdcxx::shared_ptr<TTransport>& transport,
+ const std::shared_ptr<TTransport>& transport,
uint32_t write_len) {
clear_triggers();
add_trigger(seconds, transport, write_len);
@@ -501,8 +500,8 @@
SizeGenerator& rChunkGenerator,
uint32_t maxOutstanding) {
CoupledTransports transports;
- BOOST_REQUIRE(transports.in != NULL);
- BOOST_REQUIRE(transports.out != NULL);
+ BOOST_REQUIRE(transports.in != nullptr);
+ BOOST_REQUIRE(transports.out != nullptr);
boost::shared_array<uint8_t> wbuf = boost::shared_array<uint8_t>(new uint8_t[totalSize]);
boost::shared_array<uint8_t> rbuf = boost::shared_array<uint8_t>(new uint8_t[totalSize]);
@@ -594,8 +593,8 @@
template <class CoupledTransports>
void test_read_part_available() {
CoupledTransports transports;
- BOOST_REQUIRE(transports.in != NULL);
- BOOST_REQUIRE(transports.out != NULL);
+ BOOST_REQUIRE(transports.in != nullptr);
+ BOOST_REQUIRE(transports.out != nullptr);
uint8_t write_buf[16];
uint8_t read_buf[16];
@@ -616,8 +615,8 @@
template <class CoupledTransports>
void test_read_part_available_in_chunks() {
CoupledTransports transports;
- BOOST_REQUIRE(transports.in != NULL);
- BOOST_REQUIRE(transports.out != NULL);
+ BOOST_REQUIRE(transports.in != nullptr);
+ BOOST_REQUIRE(transports.out != nullptr);
uint8_t write_buf[16];
uint8_t read_buf[16];
@@ -643,8 +642,8 @@
template <class CoupledTransports>
void test_read_partial_midframe() {
CoupledTransports transports;
- BOOST_REQUIRE(transports.in != NULL);
- BOOST_REQUIRE(transports.out != NULL);
+ BOOST_REQUIRE(transports.in != nullptr);
+ BOOST_REQUIRE(transports.out != nullptr);
uint8_t write_buf[16];
uint8_t read_buf[16];
@@ -701,8 +700,8 @@
template <class CoupledTransports>
void test_borrow_part_available() {
CoupledTransports transports;
- BOOST_REQUIRE(transports.in != NULL);
- BOOST_REQUIRE(transports.out != NULL);
+ BOOST_REQUIRE(transports.in != nullptr);
+ BOOST_REQUIRE(transports.out != nullptr);
uint8_t write_buf[16];
uint8_t read_buf[16];
@@ -716,7 +715,7 @@
uint32_t borrow_len = 10;
const uint8_t* borrowed_buf = transports.in->borrow(read_buf, &borrow_len);
BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)0);
- BOOST_CHECK(borrowed_buf == NULL);
+ BOOST_CHECK(borrowed_buf == nullptr);
clear_triggers();
}
@@ -724,12 +723,10 @@
template <class CoupledTransports>
void test_read_none_available() {
CoupledTransports transports;
- BOOST_REQUIRE(transports.in != NULL);
- BOOST_REQUIRE(transports.out != NULL);
+ BOOST_REQUIRE(transports.in != nullptr);
+ BOOST_REQUIRE(transports.out != nullptr);
- uint8_t write_buf[16];
uint8_t read_buf[16];
- memset(write_buf, 'a', sizeof(write_buf));
// Attempting to read when no data is available should either block until
// some data is available, or fail immediately. (e.g., TSocket blocks,
@@ -754,8 +751,8 @@
template <class CoupledTransports>
void test_borrow_none_available() {
CoupledTransports transports;
- BOOST_REQUIRE(transports.in != NULL);
- BOOST_REQUIRE(transports.out != NULL);
+ BOOST_REQUIRE(transports.in != nullptr);
+ BOOST_REQUIRE(transports.out != nullptr);
uint8_t write_buf[16];
memset(write_buf, 'a', sizeof(write_buf));
@@ -763,8 +760,8 @@
// Attempting to borrow when no data is available should fail immediately
set_trigger(1, transports.out, 10);
uint32_t borrow_len = 10;
- const uint8_t* borrowed_buf = transports.in->borrow(NULL, &borrow_len);
- BOOST_CHECK(borrowed_buf == NULL);
+ const uint8_t* borrowed_buf = transports.in->borrow(nullptr, &borrow_len);
+ BOOST_CHECK(borrowed_buf == nullptr);
BOOST_CHECK_EQUAL(g_numTriggersFired, (unsigned int)0);
clear_triggers();
@@ -976,11 +973,11 @@
<< rChunkSizeGen.describe() << ", " << maxOutstanding << ")";
#if (BOOST_VERSION >= 105900)
- stdcxx::function<void ()> test_func
+ std::function<void ()> test_func
#else
boost::unit_test::callback0<> test_func
#endif
- = stdcxx::bind(test_rw<CoupledTransports>,
+ = std::bind(test_rw<CoupledTransports>,
totalSize,
wSizeGen,
rSizeGen,
@@ -1026,13 +1023,13 @@
**************************************************************************/
struct global_fixture {
- stdcxx::shared_ptr<apache::thrift::concurrency::Thread> alarmThread_;
+ std::shared_ptr<apache::thrift::concurrency::Thread> alarmThread_;
global_fixture() {
#if _WIN32
apache::thrift::transport::TWinsockSingleton::create();
#endif
- apache::thrift::concurrency::PlatformThreadFactory factory;
+ apache::thrift::concurrency::ThreadFactory factory;
factory.setDetached(false);
alarmThread_ = factory.newThread(
@@ -1058,7 +1055,7 @@
#ifdef BOOST_TEST_DYN_LINK
bool init_unit_test_suite() {
struct timeval tv;
- THRIFT_GETTIMEOFDAY(&tv, NULL);
+ THRIFT_GETTIMEOFDAY(&tv, nullptr);
int seed = tv.tv_sec ^ tv.tv_usec;
initrand(seed);
diff --git a/lib/cpp/test/ZlibTest.cpp b/lib/cpp/test/ZlibTest.cpp
index ea54487..3e2eb81 100644
--- a/lib/cpp/test/ZlibTest.cpp
+++ b/lib/cpp/test/ZlibTest.cpp
@@ -36,7 +36,7 @@
#include <cstddef>
#include <fstream>
#include <iostream>
-#include <thrift/stdcxx.h>
+#include <memory>
#include <boost/random.hpp>
#include <boost/shared_array.hpp>
@@ -47,7 +47,7 @@
#include <thrift/transport/TZlibTransport.h>
using namespace apache::thrift::transport;
-using apache::thrift::stdcxx::shared_ptr;
+using std::shared_ptr;
using std::string;
boost::mt19937 rng;
@@ -58,14 +58,14 @@
class SizeGenerator {
public:
- virtual ~SizeGenerator() {}
+ virtual ~SizeGenerator() = default;
virtual unsigned int getSize() = 0;
};
class ConstantSizeGenerator : public SizeGenerator {
public:
ConstantSizeGenerator(unsigned int value) : value_(value) {}
- virtual unsigned int getSize() { return value_; }
+ unsigned int getSize() override { return value_; }
private:
unsigned int value_;
@@ -76,10 +76,10 @@
LogNormalSizeGenerator(double mean, double std_dev)
: gen_(rng, boost::lognormal_distribution<double>(mean, std_dev)) {}
- virtual unsigned int getSize() {
+ unsigned int getSize() override {
// Loop until we get a size of 1 or more
while (true) {
- unsigned int value = static_cast<unsigned int>(gen_());
+ auto value = static_cast<unsigned int>(gen_());
if (value >= 1) {
return value;
}
@@ -91,13 +91,13 @@
};
boost::shared_array<uint8_t> gen_uniform_buffer(uint32_t buf_len, uint8_t c) {
- uint8_t* buf = new uint8_t[buf_len];
+ auto* buf = new uint8_t[buf_len];
memset(buf, c, buf_len);
return boost::shared_array<uint8_t>(buf);
}
boost::shared_array<uint8_t> gen_compressible_buffer(uint32_t buf_len) {
- uint8_t* buf = new uint8_t[buf_len];
+ auto* buf = new uint8_t[buf_len];
// Generate small runs of alternately increasing and decreasing bytes
boost::uniform_smallint<uint32_t> run_length_distribution(1, 64);
@@ -129,7 +129,7 @@
}
boost::shared_array<uint8_t> gen_random_buffer(uint32_t buf_len) {
- uint8_t* buf = new uint8_t[buf_len];
+ auto* buf = new uint8_t[buf_len];
boost::uniform_smallint<uint8_t> distribution(0, UINT8_MAX);
boost::variate_generator<boost::mt19937, boost::uniform_smallint<uint8_t> >
@@ -347,8 +347,8 @@
do { \
::std::ostringstream name_ss; \
name_ss << name << "-" << BOOST_STRINGIZE(_FUNC); \
- ::apache::thrift::stdcxx::function<void ()> test_func = \
- ::apache::thrift::stdcxx::bind(_FUNC, ##__VA_ARGS__); \
+ ::std::function<void ()> test_func = \
+ ::std::bind(_FUNC, ##__VA_ARGS__); \
::boost::unit_test::test_case* tc \
= ::boost::unit_test::make_test_case(test_func, name_ss.str(), __FILE__, __LINE__); \
(suite)->add(tc); \
@@ -359,7 +359,7 @@
::std::ostringstream name_ss; \
name_ss << name << "-" << BOOST_STRINGIZE(_FUNC); \
::boost::unit_test::test_case* tc \
- = ::boost::unit_test::make_test_case(::apache::thrift::stdcxx::bind(_FUNC, \
+ = ::boost::unit_test::make_test_case(::std::bind(_FUNC, \
##__VA_ARGS__), \
name_ss.str()); \
(suite)->add(tc); \
@@ -427,7 +427,7 @@
#ifdef BOOST_TEST_DYN_LINK
bool init_unit_test_suite() {
- uint32_t seed = static_cast<uint32_t>(time(NULL));
+ auto seed = static_cast<uint32_t>(time(nullptr));
#ifdef HAVE_INTTYPES_H
printf("seed: %" PRIu32 "\n", seed);
#endif
diff --git a/lib/cpp/test/concurrency/MutexTest.cpp b/lib/cpp/test/concurrency/MutexTest.cpp
deleted file mode 100644
index 781ec1a..0000000
--- a/lib/cpp/test/concurrency/MutexTest.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.
- */
-
-// This is linked into the UnitTests test executable
-
-#include <boost/test/unit_test.hpp>
-
-#include "thrift/concurrency/Exception.h"
-#include "thrift/concurrency/Mutex.h"
-
-using boost::unit_test::test_suite;
-using boost::unit_test::framework::master_test_suite;
-
-using namespace apache::thrift::concurrency;
-
-struct LFAT
-{
- LFAT()
- : uut(Mutex::ERRORCHECK_INITIALIZER)
- {
- BOOST_CHECK_EQUAL(0, pthread_mutex_init(&mx, 0));
- BOOST_CHECK_EQUAL(0, pthread_cond_init(&cv, 0));
- }
-
- Mutex uut;
- pthread_mutex_t mx;
- pthread_cond_t cv;
-};
-
-// Helper for testing mutex behavior when locked by another thread
-void * lockFromAnotherThread(void *ptr)
-{
- struct LFAT *lfat = (LFAT *)ptr;
- BOOST_CHECK_EQUAL (0, pthread_mutex_lock(&lfat->mx)); // synchronize with testing thread
- BOOST_CHECK_NO_THROW( lfat->uut.lock());
- BOOST_CHECK_EQUAL (0, pthread_cond_signal(&lfat->cv)); // tell testing thread we have locked the mutex
- BOOST_CHECK_EQUAL (0, pthread_cond_wait(&lfat->cv, &lfat->mx)); // wait for testing thread to signal condition variable telling us to unlock
- BOOST_CHECK_NO_THROW( lfat->uut.unlock());
- return ptr; // testing thread should join to ensure completeness
-}
-
-BOOST_AUTO_TEST_SUITE(MutexTest)
-
-BOOST_AUTO_TEST_CASE(happy_path)
-{
- Mutex uut(Mutex::ERRORCHECK_INITIALIZER); // needed to test unlocking twice without undefined behavior
-
- BOOST_CHECK_NO_THROW( uut.lock());
- BOOST_CHECK_THROW ( uut.lock(), SystemResourceException); // EDEADLK (this thread owns it)
- BOOST_CHECK_NO_THROW( uut.unlock());
-}
-
-BOOST_AUTO_TEST_CASE(recursive_happy_path)
-{
- Mutex uut(Mutex::RECURSIVE_INITIALIZER);
-
- BOOST_CHECK_NO_THROW( uut.lock());
- BOOST_CHECK_NO_THROW( uut.lock());
- BOOST_CHECK_NO_THROW( uut.unlock());
- BOOST_CHECK_NO_THROW( uut.lock());
- BOOST_CHECK_NO_THROW( uut.lock());
- BOOST_CHECK_NO_THROW( uut.unlock());
- BOOST_CHECK_NO_THROW( uut.lock());
- BOOST_CHECK_NO_THROW( uut.unlock());
- BOOST_CHECK_NO_THROW( uut.unlock());
- BOOST_CHECK_NO_THROW( uut.unlock());
-}
-
-BOOST_AUTO_TEST_CASE(trylock)
-{
- Mutex uut(Mutex::ADAPTIVE_INITIALIZER); // just using another initializer for coverage
-
- BOOST_CHECK ( uut.trylock());
- BOOST_CHECK (!uut.trylock());
- BOOST_CHECK_NO_THROW( uut.unlock());
-}
-
-BOOST_AUTO_TEST_CASE(timedlock)
-{
- pthread_t th;
- struct LFAT lfat;
-
- BOOST_CHECK ( lfat.uut.timedlock(100));
- BOOST_CHECK_THROW ( lfat.uut.timedlock(100),
- SystemResourceException); // EDEADLK (current thread owns mutex - logic error)
- BOOST_CHECK_NO_THROW( lfat.uut.unlock());
-
- BOOST_CHECK_EQUAL (0, pthread_mutex_lock(&lfat.mx)); // synchronize with helper thread
- BOOST_CHECK_EQUAL (0, pthread_create(&th, NULL,
- lockFromAnotherThread, &lfat)); // create helper thread
- BOOST_CHECK_EQUAL (0, pthread_cond_wait(&lfat.cv, &lfat.mx)); // wait for helper thread to lock mutex
-
- BOOST_CHECK (!lfat.uut.timedlock(100)); // false: another thread owns the lock
-
- BOOST_CHECK_EQUAL (0, pthread_cond_signal(&lfat.cv)); // tell helper thread we are done
- BOOST_CHECK_EQUAL (0, pthread_mutex_unlock(&lfat.mx)); // let helper thread clean up
- BOOST_CHECK_EQUAL (0, pthread_join(th, 0)); // wait for testing thread to unlock and be done
-}
-
-BOOST_AUTO_TEST_CASE(underlying)
-{
- Mutex uut;
-
- BOOST_CHECK ( uut.getUnderlyingImpl());
-}
-
-BOOST_AUTO_TEST_SUITE_END()
diff --git a/lib/cpp/test/concurrency/RWMutexStarveTest.cpp b/lib/cpp/test/concurrency/RWMutexStarveTest.cpp
deleted file mode 100644
index 849e078..0000000
--- a/lib/cpp/test/concurrency/RWMutexStarveTest.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.
- */
-
-// This is linked into the UnitTests test executable
-
-#include <boost/test/unit_test.hpp>
-
-#include "thrift/concurrency/Mutex.h"
-#include "thrift/concurrency/PosixThreadFactory.h"
-#include <thrift/stdcxx.h>
-
-using apache::thrift::stdcxx::shared_ptr;
-using boost::unit_test::test_suite;
-using boost::unit_test::framework::master_test_suite;
-
-using namespace apache::thrift::concurrency;
-
-class Locker : public Runnable {
-protected:
- Locker(shared_ptr<ReadWriteMutex> rwlock, bool writer)
- : rwlock_(rwlock), writer_(writer), started_(false), gotLock_(false), signaled_(false) {}
-
-public:
- virtual void run() {
- started_ = true;
- if (writer_) {
- rwlock_->acquireWrite();
- } else {
- rwlock_->acquireRead();
- }
- gotLock_ = true;
- while (!signaled_) {
- usleep(5000);
- }
- rwlock_->release();
- }
-
- bool started() const { return started_; }
- bool gotLock() const { return gotLock_; }
- void signal() { signaled_ = true; }
-
-protected:
- shared_ptr<ReadWriteMutex> rwlock_;
- bool writer_;
- volatile bool started_;
- volatile bool gotLock_;
- volatile bool signaled_;
-};
-
-class Reader : public Locker {
-public:
- Reader(shared_ptr<ReadWriteMutex> rwlock) : Locker(rwlock, false) {}
-};
-
-class Writer : public Locker {
-public:
- Writer(shared_ptr<ReadWriteMutex> rwlock) : Locker(rwlock, true) {}
-};
-
-void test_starve(PosixThreadFactory::POLICY policy) {
- // the man pages for pthread_wrlock_rdlock suggest that any OS guarantee about
- // writer starvation may be influenced by the scheduling policy, so let's try
- // all 3 policies to see if any of them work.
- PosixThreadFactory factory(policy);
- factory.setDetached(false);
-
- shared_ptr<ReadWriteMutex> rwlock(new NoStarveReadWriteMutex());
-
- shared_ptr<Reader> reader1(new Reader(rwlock));
- shared_ptr<Reader> reader2(new Reader(rwlock));
- shared_ptr<Writer> writer(new Writer(rwlock));
-
- shared_ptr<Thread> treader1 = factory.newThread(reader1);
- shared_ptr<Thread> treader2 = factory.newThread(reader2);
- shared_ptr<Thread> twriter = factory.newThread(writer);
-
- // launch a reader and make sure he has the lock
- treader1->start();
- while (!reader1->gotLock()) {
- usleep(2000);
- }
-
- // launch a writer and make sure he's blocked on the lock
- twriter->start();
- while (!writer->started()) {
- usleep(2000);
- }
- // tricky part... we can never be 100% sure that the writer is actually
- // blocked on the lock, but we can pretty reasonably sure because we know
- // he just executed the line immediately before getting the lock, and
- // we'll wait a full second for him to get on it.
- sleep(1);
-
- // launch a second reader... if the RWMutex guarantees that writers won't
- // starve, this reader should not be able to acquire the lock until the writer
- // has acquired and released it.
- treader2->start();
- while (!reader2->started()) {
- usleep(2000);
- }
- // again... can't be 100% sure the reader is waiting on (or has) the lock
- // but we can be close.
- sleep(1);
-
- // tell reader 1 to let go of the lock
- reader1->signal();
-
- // wait for someone to get the lock
- while (!reader2->gotLock() && !writer->gotLock()) {
- usleep(2000);
- }
-
- // the test succeeded if the WRITER got the lock.
- bool success = writer->gotLock();
-
- // tell everyone we're done and wait for them to finish
- reader2->signal();
- writer->signal();
- treader1->join();
- treader2->join();
- twriter->join();
-
- // make sure it worked.
- BOOST_CHECK_MESSAGE(success, "writer is starving");
-}
-
-BOOST_AUTO_TEST_SUITE(RWMutexStarveTest)
-
-BOOST_AUTO_TEST_CASE(test_starve_other) {
- test_starve(PosixThreadFactory::OTHER);
-}
-
-BOOST_AUTO_TEST_CASE(test_starve_rr) {
- test_starve(PosixThreadFactory::ROUND_ROBIN);
-}
-
-BOOST_AUTO_TEST_CASE(test_starve_fifo) {
- test_starve(PosixThreadFactory::FIFO);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
diff --git a/lib/cpp/test/concurrency/Tests.cpp b/lib/cpp/test/concurrency/Tests.cpp
index fc0ba7f..8c734c2 100644
--- a/lib/cpp/test/concurrency/Tests.cpp
+++ b/lib/cpp/test/concurrency/Tests.cpp
@@ -31,8 +31,6 @@
int main(int argc, char** argv) {
- std::string arg;
-
std::vector<std::string> args(argc - 1 > 1 ? argc - 1 : 1);
args[0] = "all";
@@ -41,7 +39,7 @@
args[ix - 1] = std::string(argv[ix]);
}
- if (getenv("VALGRIND") != 0) {
+ if (getenv("VALGRIND") != nullptr) {
// lower the scale of every test
WEIGHT = 1;
}
@@ -94,18 +92,18 @@
std::cout << "\t\tUtil minimum time" << std::endl;
- int64_t time00 = Util::currentTime();
- int64_t time01 = Util::currentTime();
+ int64_t time00 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
+ int64_t time01 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
std::cout << "\t\t\tMinimum time: " << time01 - time00 << "ms" << std::endl;
- time00 = Util::currentTime();
+ time00 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
time01 = time00;
size_t count = 0;
while (time01 < time00 + 10) {
count++;
- time01 = Util::currentTime();
+ time01 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
std::cout << "\t\t\tscall per ms: " << count / (time01 - time00) << std::endl;
diff --git a/lib/cpp/test/concurrency/ThreadFactoryTests.h b/lib/cpp/test/concurrency/ThreadFactoryTests.h
index 48330f3..febe3f8 100644
--- a/lib/cpp/test/concurrency/ThreadFactoryTests.h
+++ b/lib/cpp/test/concurrency/ThreadFactoryTests.h
@@ -19,10 +19,9 @@
#include <thrift/thrift-config.h>
#include <thrift/concurrency/Thread.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/Mutex.h>
-#include <thrift/concurrency/Util.h>
#include <assert.h>
#include <iostream>
@@ -33,7 +32,7 @@
namespace concurrency {
namespace test {
-using stdcxx::shared_ptr;
+using std::shared_ptr;
using namespace apache::thrift::concurrency;
/**
@@ -52,7 +51,7 @@
public:
ReapNTask(Monitor& monitor, int& activeCount) : _monitor(monitor), _count(activeCount) {}
- void run() {
+ void run() override {
Synchronized s(_monitor);
if (--_count == 0) {
@@ -66,7 +65,7 @@
bool reapNThreads(int loop = 1, int count = 10) {
- PlatformThreadFactory threadFactory = PlatformThreadFactory();
+ ThreadFactory threadFactory = ThreadFactory();
shared_ptr<Monitor> monitor(new Monitor);
for (int lix = 0; lix < loop; lix++) {
@@ -123,7 +122,7 @@
SynchStartTask(Monitor& monitor, volatile STATE& state) : _monitor(monitor), _state(state) {}
- void run() {
+ void run() override {
{
Synchronized s(_monitor);
if (_state == SynchStartTask::STARTING) {
@@ -159,7 +158,7 @@
shared_ptr<SynchStartTask> task
= shared_ptr<SynchStartTask>(new SynchStartTask(monitor, state));
- PlatformThreadFactory threadFactory = PlatformThreadFactory();
+ ThreadFactory threadFactory = ThreadFactory();
shared_ptr<Thread> thread = threadFactory.newThread(task);
@@ -221,7 +220,7 @@
Monitor monitor;
- int64_t startTime = Util::currentTime();
+ int64_t startTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
for (int64_t ix = 0; ix < count; ix++) {
{
@@ -233,7 +232,7 @@
}
}
- int64_t endTime = Util::currentTime();
+ int64_t endTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
bool success = (endTime - startTime) >= (count * timeout);
@@ -248,14 +247,14 @@
class FloodTask : public Runnable {
public:
FloodTask(const size_t id, Monitor& mon) : _id(id), _mon(mon) {}
- ~FloodTask() {
+ ~FloodTask() override {
if (_id % 10000 == 0) {
Synchronized sync(_mon);
std::cout << "\t\tthread " << _id << " done" << std::endl;
}
}
- void run() {
+ void run() override {
if (_id % 10000 == 0) {
Synchronized sync(_mon);
std::cout << "\t\tthread " << _id << " started" << std::endl;
@@ -265,7 +264,7 @@
Monitor& _mon;
};
- void foo(PlatformThreadFactory* tf) { (void)tf; }
+ void foo(ThreadFactory* tf) { (void)tf; }
bool floodNTest(size_t loop = 1, size_t count = 100000) {
@@ -274,7 +273,7 @@
for (size_t lix = 0; lix < loop; lix++) {
- PlatformThreadFactory threadFactory = PlatformThreadFactory();
+ ThreadFactory threadFactory = ThreadFactory();
threadFactory.setDetached(true);
for (size_t tix = 0; tix < count; tix++) {
diff --git a/lib/cpp/test/concurrency/ThreadManagerTests.h b/lib/cpp/test/concurrency/ThreadManagerTests.h
index 9ecd6ba..fee7c7c 100644
--- a/lib/cpp/test/concurrency/ThreadManagerTests.h
+++ b/lib/cpp/test/concurrency/ThreadManagerTests.h
@@ -19,9 +19,8 @@
#include <thrift/thrift-config.h>
#include <thrift/concurrency/ThreadManager.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/Util.h>
#include <assert.h>
#include <deque>
@@ -36,8 +35,8 @@
using namespace apache::thrift::concurrency;
-static std::deque<stdcxx::shared_ptr<Runnable> > m_expired;
-static void expiredNotifier(stdcxx::shared_ptr<Runnable> runnable)
+static std::deque<std::shared_ptr<Runnable> > m_expired;
+static void expiredNotifier(std::shared_ptr<Runnable> runnable)
{
m_expired.push_back(runnable);
}
@@ -64,13 +63,13 @@
Task(Monitor& monitor, size_t& count, int64_t timeout)
: _monitor(monitor), _count(count), _timeout(timeout), _startTime(0), _endTime(0), _done(false) {}
- void run() {
+ void run() override {
- _startTime = Util::currentTime();
+ _startTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
sleep_(_timeout);
- _endTime = Util::currentTime();
+ _endTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
_done = true;
@@ -108,12 +107,9 @@
shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workerCount);
- shared_ptr<PlatformThreadFactory> threadFactory
- = shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory(false));
+ shared_ptr<ThreadFactory> threadFactory
+ = shared_ptr<ThreadFactory>(new ThreadFactory(false));
-#if !USE_BOOST_THREAD && !USE_STD_THREAD
- threadFactory->setPriority(PosixThreadFactory::HIGHEST);
-#endif
threadManager->threadFactory(threadFactory);
threadManager->start();
@@ -126,9 +122,9 @@
new ThreadManagerTests::Task(monitor, activeCount, timeout)));
}
- int64_t time00 = Util::currentTime();
+ int64_t time00 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
- for (std::set<shared_ptr<ThreadManagerTests::Task> >::iterator ix = tasks.begin();
+ for (auto ix = tasks.begin();
ix != tasks.end();
ix++) {
@@ -146,7 +142,7 @@
}
}
- int64_t time01 = Util::currentTime();
+ int64_t time01 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
int64_t firstTime = 9223372036854775807LL;
int64_t lastTime = 0;
@@ -155,7 +151,7 @@
int64_t minTime = 9223372036854775807LL;
int64_t maxTime = 0;
- for (std::set<shared_ptr<ThreadManagerTests::Task> >::iterator ix = tasks.begin();
+ for (auto ix = tasks.begin();
ix != tasks.end();
ix++) {
@@ -205,7 +201,7 @@
BlockTask(Monitor& entryMonitor, Monitor& blockMonitor, bool& blocked, Monitor& doneMonitor, size_t& count)
: _entryMonitor(entryMonitor), _entered(false), _blockMonitor(blockMonitor), _blocked(blocked), _doneMonitor(doneMonitor), _count(count) {}
- void run() {
+ void run() override {
{
Synchronized s(_entryMonitor);
_entered = true;
@@ -257,12 +253,9 @@
shared_ptr<ThreadManager> threadManager
= ThreadManager::newSimpleThreadManager(workerCount, pendingTaskMaxCount);
- shared_ptr<PlatformThreadFactory> threadFactory
- = shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory());
+ shared_ptr<ThreadFactory> threadFactory
+ = shared_ptr<ThreadFactory>(new ThreadFactory());
-#if !USE_BOOST_THREAD && !USE_STD_THREAD
- threadFactory->setPriority(PosixThreadFactory::HIGHEST);
-#endif
threadManager->threadFactory(threadFactory);
threadManager->start();
@@ -282,7 +275,7 @@
new ThreadManagerTests::BlockTask(entryMonitor, blockMonitor, blocked[1], doneMonitor, activeCounts[1])));
}
- for (std::vector<shared_ptr<ThreadManagerTests::BlockTask> >::iterator ix = tasks.begin();
+ for (auto ix = tasks.begin();
ix != tasks.end();
ix++) {
threadManager->add(*ix);
@@ -393,66 +386,27 @@
bool apiTest() {
// prove currentTime has milliseconds granularity since many other things depend on it
- int64_t a = Util::currentTime();
+ int64_t a = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
sleep_(100);
- int64_t b = Util::currentTime();
+ int64_t b = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
if (b - a < 50 || b - a > 150) {
std::cerr << "\t\t\texpected 100ms gap, found " << (b-a) << "ms gap instead." << std::endl;
return false;
}
-#if !USE_BOOST_THREAD && !USE_STD_THREAD
- // test once with a detached thread factory and once with a joinable thread factory
-
- shared_ptr<PosixThreadFactory> threadFactory
- = shared_ptr<PosixThreadFactory>(new PosixThreadFactory(false));
-
- std::cout << "\t\t\tapiTest with joinable thread factory" << std::endl;
- if (!apiTestWithThreadFactory(threadFactory)) {
- return false;
- }
-
- threadFactory.reset(new PosixThreadFactory(true));
- std::cout << "\t\t\tapiTest with detached thread factory" << std::endl;
- return apiTestWithThreadFactory(threadFactory);
-#else
- return apiTestWithThreadFactory(shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory()));
-#endif
+ return apiTestWithThreadFactory(shared_ptr<ThreadFactory>(new ThreadFactory()));
}
- bool apiTestWithThreadFactory(shared_ptr<PlatformThreadFactory> threadFactory)
+ bool apiTestWithThreadFactory(shared_ptr<ThreadFactory> threadFactory)
{
shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(1);
threadManager->threadFactory(threadFactory);
-#if !USE_BOOST_THREAD && !USE_STD_THREAD
- threadFactory->setPriority(PosixThreadFactory::HIGHEST);
-
- // verify we cannot change the thread factory to one with the opposite detached setting
- shared_ptr<PlatformThreadFactory> threadFactory2
- = shared_ptr<PosixThreadFactory>(new PlatformThreadFactory(
- PosixThreadFactory::ROUND_ROBIN,
- PosixThreadFactory::NORMAL,
- 1,
- !threadFactory->isDetached()));
- try {
- threadManager->threadFactory(threadFactory2);
- // if the call succeeded we changed the thread factory to one that had the opposite setting for "isDetached()".
- // this is bad, because the thread manager checks with the thread factory to see if it should join threads
- // as they are leaving - so the detached status of new threads cannot change while there are existing threads.
- std::cerr << "\t\t\tShould not be able to change thread factory detached disposition" << std::endl;
- return false;
- }
- catch (InvalidArgumentException& ex) {
- /* expected */
- }
-#endif
-
std::cout << "\t\t\t\tstarting.. " << std::endl;
threadManager->start();
- threadManager->setExpireCallback(expiredNotifier); // apache::thrift::stdcxx::bind(&ThreadManagerTests::expiredNotifier, this));
+ threadManager->setExpireCallback(expiredNotifier); // std::bind(&ThreadManagerTests::expiredNotifier, this));
#define EXPECT(FUNC, COUNT) { size_t c = FUNC; if (c != COUNT) { std::cerr << "expected " #FUNC" to be " #COUNT ", but was " << c << std::endl; return false; } }
diff --git a/lib/cpp/test/concurrency/TimerManagerTests.h b/lib/cpp/test/concurrency/TimerManagerTests.h
index 1c52c47..2d1a262 100644
--- a/lib/cpp/test/concurrency/TimerManagerTests.h
+++ b/lib/cpp/test/concurrency/TimerManagerTests.h
@@ -18,11 +18,12 @@
*/
#include <thrift/concurrency/TimerManager.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/Util.h>
#include <assert.h>
+#include <chrono>
+#include <thread>
#include <iostream>
namespace apache {
@@ -37,19 +38,19 @@
public:
class Task : public Runnable {
public:
- Task(Monitor& monitor, int64_t timeout)
+ Task(Monitor& monitor, uint64_t timeout)
: _timeout(timeout),
- _startTime(Util::currentTime()),
+ _startTime(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count()),
_endTime(0),
_monitor(monitor),
_success(false),
_done(false) {}
- ~Task() { std::cerr << this << std::endl; }
+ ~Task() override { std::cerr << this << std::endl; }
- void run() {
+ void run() override {
- _endTime = Util::currentTime();
+ _endTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
_success = (_endTime - _startTime) >= _timeout;
{
@@ -73,14 +74,14 @@
* properly clean up itself and the remaining orphaned timeout task when the
* manager goes out of scope and its destructor is called.
*/
- bool test00(int64_t timeout = 1000LL) {
+ bool test00(uint64_t timeout = 1000LL) {
shared_ptr<TimerManagerTests::Task> orphanTask
= shared_ptr<TimerManagerTests::Task>(new TimerManagerTests::Task(_monitor, 10 * timeout));
{
TimerManager timerManager;
- timerManager.threadFactory(shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory()));
+ timerManager.threadFactory(shared_ptr<ThreadFactory>(new ThreadFactory()));
timerManager.start();
if (timerManager.state() != TimerManager::STARTED) {
std::cerr << "timerManager is not in the STARTED state, but should be" << std::endl;
@@ -95,7 +96,7 @@
Synchronized s(_monitor);
timerManager.add(orphanTask, 10 * timeout);
- THRIFT_SLEEP_USEC(timeout * 1000);
+ std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
task.reset(new TimerManagerTests::Task(_monitor, timeout));
timerManager.add(task, timeout);
@@ -123,9 +124,9 @@
* verifies that the timer manager properly clean up itself and the remaining orphaned timeout
* task when the manager goes out of scope and its destructor is called.
*/
- bool test01(int64_t timeout = 1000LL) {
+ bool test01(uint64_t timeout = 1000LL) {
TimerManager timerManager;
- timerManager.threadFactory(shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory()));
+ timerManager.threadFactory(shared_ptr<ThreadFactory>(new ThreadFactory()));
timerManager.start();
assert(timerManager.state() == TimerManager::STARTED);
@@ -156,9 +157,9 @@
* clean up itself and the remaining orphaned timeout task when the manager goes out of scope
* and its destructor is called.
*/
- bool test02(int64_t timeout = 1000LL) {
+ bool test02(uint64_t timeout = 1000LL) {
TimerManager timerManager;
- timerManager.threadFactory(shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory()));
+ timerManager.threadFactory(shared_ptr<ThreadFactory>(new ThreadFactory()));
timerManager.start();
assert(timerManager.state() == TimerManager::STARTED);
@@ -189,9 +190,9 @@
* verifies that the timer manager properly clean up itself and the remaining orphaned timeout
* task when the manager goes out of scope and its destructor is called.
*/
- bool test03(int64_t timeout = 1000LL) {
+ bool test03(uint64_t timeout = 1000LL) {
TimerManager timerManager;
- timerManager.threadFactory(shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory()));
+ timerManager.threadFactory(shared_ptr<ThreadFactory>(new ThreadFactory()));
timerManager.start();
assert(timerManager.state() == TimerManager::STARTED);
@@ -216,7 +217,7 @@
// Verify behavior when removing the removed task
try {
timerManager.remove(timer);
- assert(0 == "ERROR: This remove should send a NoSuchTaskException exception.");
+ assert(nullptr == "ERROR: This remove should send a NoSuchTaskException exception.");
} catch (NoSuchTaskException&) {
}
@@ -224,11 +225,11 @@
}
/**
- * This test creates one tasks, and tries to remove it after it has expired.
+ * This test creates one task, and tries to remove it after it has expired.
*/
- bool test04(int64_t timeout = 1000LL) {
+ bool test04(uint64_t timeout = 1000LL) {
TimerManager timerManager;
- timerManager.threadFactory(shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory()));
+ timerManager.threadFactory(shared_ptr<ThreadFactory>(new ThreadFactory()));
timerManager.start();
assert(timerManager.state() == TimerManager::STARTED);
@@ -238,15 +239,24 @@
shared_ptr<TimerManagerTests::Task> task
= shared_ptr<TimerManagerTests::Task>(new TimerManagerTests::Task(_monitor, timeout / 10));
TimerManager::Timer timer = timerManager.add(task, task->_timeout);
+ task.reset();
// Wait until the task has completed
_monitor.wait(timeout);
// Verify behavior when removing the expired task
- try {
- timerManager.remove(timer);
- assert(0 == "ERROR: This remove should send a NoSuchTaskException exception.");
- } catch (NoSuchTaskException&) {
+ // notify is called inside the task so the task may still
+ // be running when we get here, so we need to loop...
+ for (;;) {
+ try {
+ timerManager.remove(timer);
+ assert(nullptr == "ERROR: This remove should throw NoSuchTaskException, or UncancellableTaskException.");
+ } catch (const NoSuchTaskException&) {
+ break;
+ } catch (const UncancellableTaskException&) {
+ // the thread was still exiting; try again...
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ }
}
return true;
diff --git a/lib/cpp/test/processor/EventLog.cpp b/lib/cpp/test/processor/EventLog.cpp
index e3ddbcc..c8e0d9b 100644
--- a/lib/cpp/test/processor/EventLog.cpp
+++ b/lib/cpp/test/processor/EventLog.cpp
@@ -110,7 +110,7 @@
Event EventLog::waitForConnEvent(uint32_t connId, int64_t timeout) {
Synchronized s(monitor_);
- EventList::iterator it = events_.begin();
+ auto it = events_.begin();
while (true) {
try {
// TODO: it would be nicer to honor timeout for the duration of this
diff --git a/lib/cpp/test/processor/Handlers.h b/lib/cpp/test/processor/Handlers.h
index ad47229..05d19ed 100644
--- a/lib/cpp/test/processor/Handlers.h
+++ b/lib/cpp/test/processor/Handlers.h
@@ -29,34 +29,34 @@
class ParentHandler : virtual public ParentServiceIf {
public:
- ParentHandler(const stdcxx::shared_ptr<EventLog>& log)
+ ParentHandler(const std::shared_ptr<EventLog>& log)
: triggerMonitor(&mutex_), generation_(0), wait_(false), log_(log) {}
- int32_t incrementGeneration() {
+ int32_t incrementGeneration() override {
concurrency::Guard g(mutex_);
log_->append(EventLog::ET_CALL_INCREMENT_GENERATION, 0, 0);
return ++generation_;
}
- int32_t getGeneration() {
+ int32_t getGeneration() override {
concurrency::Guard g(mutex_);
log_->append(EventLog::ET_CALL_GET_GENERATION, 0, 0);
return generation_;
}
- void addString(const std::string& s) {
+ void addString(const std::string& s) override {
concurrency::Guard g(mutex_);
log_->append(EventLog::ET_CALL_ADD_STRING, 0, 0);
strings_.push_back(s);
}
- void getStrings(std::vector<std::string>& _return) {
+ void getStrings(std::vector<std::string>& _return) override {
concurrency::Guard g(mutex_);
log_->append(EventLog::ET_CALL_GET_STRINGS, 0, 0);
_return = strings_;
}
- void getDataWait(std::string& _return, const int32_t length) {
+ void getDataWait(std::string& _return, const int32_t length) override {
concurrency::Guard g(mutex_);
log_->append(EventLog::ET_CALL_GET_DATA_WAIT, 0, 0);
@@ -65,14 +65,14 @@
_return.append(length, 'a');
}
- void onewayWait() {
+ void onewayWait() override {
concurrency::Guard g(mutex_);
log_->append(EventLog::ET_CALL_ONEWAY_WAIT, 0, 0);
blockUntilTriggered();
}
- void exceptionWait(const std::string& message) {
+ void exceptionWait(const std::string& message) override {
concurrency::Guard g(mutex_);
log_->append(EventLog::ET_CALL_EXCEPTION_WAIT, 0, 0);
@@ -83,7 +83,7 @@
throw e;
}
- void unexpectedExceptionWait(const std::string& message) {
+ void unexpectedExceptionWait(const std::string& message) override {
concurrency::Guard g(mutex_);
log_->append(EventLog::ET_CALL_UNEXPECTED_EXCEPTION_WAIT, 0, 0);
@@ -136,7 +136,7 @@
int32_t generation_;
bool wait_;
std::vector<std::string> strings_;
- stdcxx::shared_ptr<EventLog> log_;
+ std::shared_ptr<EventLog> log_;
};
#ifdef _WIN32
@@ -146,9 +146,9 @@
class ChildHandler : public ParentHandler, virtual public ChildServiceIf {
public:
- ChildHandler(const stdcxx::shared_ptr<EventLog>& log) : ParentHandler(log), value_(0) {}
+ ChildHandler(const std::shared_ptr<EventLog>& log) : ParentHandler(log), value_(0) {}
- int32_t setValue(const int32_t value) {
+ int32_t setValue(const int32_t value) override {
concurrency::Guard g(mutex_);
log_->append(EventLog::ET_CALL_SET_VALUE, 0, 0);
@@ -157,7 +157,7 @@
return oldValue;
}
- int32_t getValue() {
+ int32_t getValue() override {
concurrency::Guard g(mutex_);
log_->append(EventLog::ET_CALL_GET_VALUE, 0, 0);
@@ -174,13 +174,13 @@
struct ConnContext {
public:
- ConnContext(stdcxx::shared_ptr<protocol::TProtocol> in,
- stdcxx::shared_ptr<protocol::TProtocol> out,
+ ConnContext(std::shared_ptr<protocol::TProtocol> in,
+ std::shared_ptr<protocol::TProtocol> out,
uint32_t id)
: input(in), output(out), id(id) {}
- stdcxx::shared_ptr<protocol::TProtocol> input;
- stdcxx::shared_ptr<protocol::TProtocol> output;
+ std::shared_ptr<protocol::TProtocol> input;
+ std::shared_ptr<protocol::TProtocol> output;
uint32_t id;
};
@@ -196,22 +196,22 @@
class ServerEventHandler : public server::TServerEventHandler {
public:
- ServerEventHandler(const stdcxx::shared_ptr<EventLog>& log) : nextId_(1), log_(log) {}
+ ServerEventHandler(const std::shared_ptr<EventLog>& log) : nextId_(1), log_(log) {}
- virtual void preServe() {}
+ void preServe() override {}
- virtual void* createContext(stdcxx::shared_ptr<protocol::TProtocol> input,
- stdcxx::shared_ptr<protocol::TProtocol> output) {
+ void* createContext(std::shared_ptr<protocol::TProtocol> input,
+ std::shared_ptr<protocol::TProtocol> output) override {
ConnContext* context = new ConnContext(input, output, nextId_);
++nextId_;
log_->append(EventLog::ET_CONN_CREATED, context->id, 0);
return context;
}
- virtual void deleteContext(void* serverContext,
- stdcxx::shared_ptr<protocol::TProtocol> input,
- stdcxx::shared_ptr<protocol::TProtocol> output) {
- ConnContext* context = reinterpret_cast<ConnContext*>(serverContext);
+ void deleteContext(void* serverContext,
+ std::shared_ptr<protocol::TProtocol> input,
+ std::shared_ptr<protocol::TProtocol> output) override {
+ auto* context = reinterpret_cast<ConnContext*>(serverContext);
if (input != context->input) {
abort();
@@ -225,8 +225,8 @@
delete context;
}
- virtual void processContext(void* serverContext,
- stdcxx::shared_ptr<transport::TTransport> transport) {
+ void processContext(void* serverContext,
+ std::shared_ptr<transport::TTransport> transport) override {
// TODO: We currently don't test the behavior of the processContext()
// calls. The various server implementations call processContext() at
// slightly different times, and it is too annoying to try and account for
@@ -251,15 +251,15 @@
protected:
uint32_t nextId_;
- stdcxx::shared_ptr<EventLog> log_;
+ std::shared_ptr<EventLog> log_;
};
class ProcessorEventHandler : public TProcessorEventHandler {
public:
- ProcessorEventHandler(const stdcxx::shared_ptr<EventLog>& log) : nextId_(1), log_(log) {}
+ ProcessorEventHandler(const std::shared_ptr<EventLog>& log) : nextId_(1), log_(log) {}
- void* getContext(const char* fnName, void* serverContext) {
- ConnContext* connContext = reinterpret_cast<ConnContext*>(serverContext);
+ void* getContext(const char* fnName, void* serverContext) override {
+ auto* connContext = reinterpret_cast<ConnContext*>(serverContext);
CallContext* context = new CallContext(connContext, nextId_, fnName);
++nextId_;
@@ -268,47 +268,47 @@
return context;
}
- void freeContext(void* ctx, const char* fnName) {
- CallContext* context = reinterpret_cast<CallContext*>(ctx);
+ void freeContext(void* ctx, const char* fnName) override {
+ auto* context = reinterpret_cast<CallContext*>(ctx);
checkName(context, fnName);
log_->append(EventLog::ET_CALL_FINISHED, context->connContext->id, context->id, fnName);
delete context;
}
- void preRead(void* ctx, const char* fnName) {
- CallContext* context = reinterpret_cast<CallContext*>(ctx);
+ void preRead(void* ctx, const char* fnName) override {
+ auto* context = reinterpret_cast<CallContext*>(ctx);
checkName(context, fnName);
log_->append(EventLog::ET_PRE_READ, context->connContext->id, context->id, fnName);
}
- void postRead(void* ctx, const char* fnName, uint32_t bytes) {
+ void postRead(void* ctx, const char* fnName, uint32_t bytes) override {
THRIFT_UNUSED_VARIABLE(bytes);
- CallContext* context = reinterpret_cast<CallContext*>(ctx);
+ auto* context = reinterpret_cast<CallContext*>(ctx);
checkName(context, fnName);
log_->append(EventLog::ET_POST_READ, context->connContext->id, context->id, fnName);
}
- void preWrite(void* ctx, const char* fnName) {
- CallContext* context = reinterpret_cast<CallContext*>(ctx);
+ void preWrite(void* ctx, const char* fnName) override {
+ auto* context = reinterpret_cast<CallContext*>(ctx);
checkName(context, fnName);
log_->append(EventLog::ET_PRE_WRITE, context->connContext->id, context->id, fnName);
}
- void postWrite(void* ctx, const char* fnName, uint32_t bytes) {
+ void postWrite(void* ctx, const char* fnName, uint32_t bytes) override {
THRIFT_UNUSED_VARIABLE(bytes);
- CallContext* context = reinterpret_cast<CallContext*>(ctx);
+ auto* context = reinterpret_cast<CallContext*>(ctx);
checkName(context, fnName);
log_->append(EventLog::ET_POST_WRITE, context->connContext->id, context->id, fnName);
}
- void asyncComplete(void* ctx, const char* fnName) {
- CallContext* context = reinterpret_cast<CallContext*>(ctx);
+ void asyncComplete(void* ctx, const char* fnName) override {
+ auto* context = reinterpret_cast<CallContext*>(ctx);
checkName(context, fnName);
log_->append(EventLog::ET_ASYNC_COMPLETE, context->connContext->id, context->id, fnName);
}
- void handlerError(void* ctx, const char* fnName) {
- CallContext* context = reinterpret_cast<CallContext*>(ctx);
+ void handlerError(void* ctx, const char* fnName) override {
+ auto* context = reinterpret_cast<CallContext*>(ctx);
checkName(context, fnName);
log_->append(EventLog::ET_HANDLER_ERROR, context->connContext->id, context->id, fnName);
}
@@ -329,7 +329,7 @@
}
uint32_t nextId_;
- stdcxx::shared_ptr<EventLog> log_;
+ std::shared_ptr<EventLog> log_;
};
}
}
diff --git a/lib/cpp/test/processor/ProcessorTest.cpp b/lib/cpp/test/processor/ProcessorTest.cpp
index c9e186f..a36ef3e 100644
--- a/lib/cpp/test/processor/ProcessorTest.cpp
+++ b/lib/cpp/test/processor/ProcessorTest.cpp
@@ -25,7 +25,7 @@
#include <boost/test/unit_test.hpp>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/concurrency/Monitor.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TThreadedServer.h>
@@ -57,13 +57,13 @@
public:
typedef TSimpleServer ServerType;
- stdcxx::shared_ptr<TSimpleServer> createServer(
- const stdcxx::shared_ptr<TProcessor>& processor,
+ std::shared_ptr<TSimpleServer> createServer(
+ const std::shared_ptr<TProcessor>& processor,
uint16_t port,
- const stdcxx::shared_ptr<TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory) {
- stdcxx::shared_ptr<TServerSocket> socket(new TServerSocket(port));
- return stdcxx::shared_ptr<TSimpleServer>(
+ const std::shared_ptr<TTransportFactory>& transportFactory,
+ const std::shared_ptr<TProtocolFactory>& protocolFactory) {
+ std::shared_ptr<TServerSocket> socket(new TServerSocket(port));
+ return std::shared_ptr<TSimpleServer>(
new TSimpleServer(processor, socket, transportFactory, protocolFactory));
}
};
@@ -72,13 +72,13 @@
public:
typedef TThreadedServer ServerType;
- stdcxx::shared_ptr<TThreadedServer> createServer(
- const stdcxx::shared_ptr<TProcessor>& processor,
+ std::shared_ptr<TThreadedServer> createServer(
+ const std::shared_ptr<TProcessor>& processor,
uint16_t port,
- const stdcxx::shared_ptr<TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory) {
- stdcxx::shared_ptr<TServerSocket> socket(new TServerSocket(port));
- return stdcxx::shared_ptr<TThreadedServer>(
+ const std::shared_ptr<TTransportFactory>& transportFactory,
+ const std::shared_ptr<TProtocolFactory>& protocolFactory) {
+ std::shared_ptr<TServerSocket> socket(new TServerSocket(port));
+ return std::shared_ptr<TThreadedServer>(
new TThreadedServer(processor, socket, transportFactory, protocolFactory));
}
};
@@ -87,19 +87,19 @@
public:
typedef TThreadPoolServer ServerType;
- stdcxx::shared_ptr<TThreadPoolServer> createServer(
- const stdcxx::shared_ptr<TProcessor>& processor,
+ std::shared_ptr<TThreadPoolServer> createServer(
+ const std::shared_ptr<TProcessor>& processor,
uint16_t port,
- const stdcxx::shared_ptr<TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory) {
- stdcxx::shared_ptr<TServerSocket> socket(new TServerSocket(port));
+ const std::shared_ptr<TTransportFactory>& transportFactory,
+ const std::shared_ptr<TProtocolFactory>& protocolFactory) {
+ std::shared_ptr<TServerSocket> socket(new TServerSocket(port));
- stdcxx::shared_ptr<PlatformThreadFactory> threadFactory(new PlatformThreadFactory);
- stdcxx::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(8);
+ std::shared_ptr<ThreadFactory> threadFactory(new ThreadFactory);
+ std::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(8);
threadManager->threadFactory(threadFactory);
threadManager->start();
- return stdcxx::shared_ptr<TThreadPoolServer>(
+ return std::shared_ptr<TThreadPoolServer>(
new TThreadPoolServer(processor, socket, transportFactory, protocolFactory, threadManager));
}
};
@@ -108,27 +108,27 @@
public:
typedef TNonblockingServer ServerType;
- stdcxx::shared_ptr<TNonblockingServer> createServer(
- const stdcxx::shared_ptr<TProcessor>& processor,
+ std::shared_ptr<TNonblockingServer> createServer(
+ const std::shared_ptr<TProcessor>& processor,
uint16_t port,
- const stdcxx::shared_ptr<TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory) {
+ const std::shared_ptr<TTransportFactory>& transportFactory,
+ const std::shared_ptr<TProtocolFactory>& protocolFactory) {
// TNonblockingServer automatically uses TFramedTransport.
// Raise an exception if the supplied transport factory is not a
// TFramedTransportFactory
- TFramedTransportFactory* framedFactory
+ auto* framedFactory
= dynamic_cast<TFramedTransportFactory*>(transportFactory.get());
- if (framedFactory == NULL) {
+ if (framedFactory == nullptr) {
throw TException("TNonblockingServer must use TFramedTransport");
}
- stdcxx::shared_ptr<TNonblockingServerSocket> socket(new TNonblockingServerSocket(port));
- stdcxx::shared_ptr<PlatformThreadFactory> threadFactory(new PlatformThreadFactory);
- stdcxx::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(8);
+ std::shared_ptr<TNonblockingServerSocket> socket(new TNonblockingServerSocket(port));
+ std::shared_ptr<ThreadFactory> threadFactory(new ThreadFactory);
+ std::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(8);
threadManager->threadFactory(threadFactory);
threadManager->start();
- return stdcxx::shared_ptr<TNonblockingServer>(
+ return std::shared_ptr<TNonblockingServer>(
new TNonblockingServer(processor, protocolFactory, socket, threadManager));
}
};
@@ -137,24 +137,24 @@
public:
typedef TNonblockingServer ServerType;
- stdcxx::shared_ptr<TNonblockingServer> createServer(
- const stdcxx::shared_ptr<TProcessor>& processor,
+ std::shared_ptr<TNonblockingServer> createServer(
+ const std::shared_ptr<TProcessor>& processor,
uint16_t port,
- const stdcxx::shared_ptr<TTransportFactory>& transportFactory,
- const stdcxx::shared_ptr<TProtocolFactory>& protocolFactory) {
+ const std::shared_ptr<TTransportFactory>& transportFactory,
+ const std::shared_ptr<TProtocolFactory>& protocolFactory) {
// TNonblockingServer automatically uses TFramedTransport.
// Raise an exception if the supplied transport factory is not a
// TFramedTransportFactory
- TFramedTransportFactory* framedFactory
+ auto* framedFactory
= dynamic_cast<TFramedTransportFactory*>(transportFactory.get());
- if (framedFactory == NULL) {
+ if (framedFactory == nullptr) {
throw TException("TNonblockingServer must use TFramedTransport");
}
- stdcxx::shared_ptr<TNonblockingServerSocket> socket(new TNonblockingServerSocket(port));
+ std::shared_ptr<TNonblockingServerSocket> socket(new TNonblockingServerSocket(port));
// Use a NULL ThreadManager
- stdcxx::shared_ptr<ThreadManager> threadManager;
- return stdcxx::shared_ptr<TNonblockingServer>(
+ std::shared_ptr<ThreadManager> threadManager;
+ return std::shared_ptr<TNonblockingServer>(
new TNonblockingServer(processor, protocolFactory, socket, threadManager));
}
};
@@ -244,48 +244,48 @@
processor_->setEventHandler(processorEventHandler_);
}
- stdcxx::shared_ptr<TServer> createServer(uint16_t port) {
+ std::shared_ptr<TServer> createServer(uint16_t port) override {
ServerTraits_ serverTraits;
return serverTraits.createServer(processor_, port, transportFactory_, protocolFactory_);
}
- stdcxx::shared_ptr<TServerEventHandler> getServerEventHandler() { return serverEventHandler_; }
+ std::shared_ptr<TServerEventHandler> getServerEventHandler() override { return serverEventHandler_; }
- void bindSuccessful(uint16_t port) { port_ = port; }
+ void bindSuccessful(uint16_t port) override { port_ = port; }
uint16_t getPort() const { return port_; }
- const stdcxx::shared_ptr<EventLog>& getLog() const { return log_; }
+ const std::shared_ptr<EventLog>& getLog() const { return log_; }
- const stdcxx::shared_ptr<Handler>& getHandler() const { return handler_; }
+ const std::shared_ptr<Handler>& getHandler() const { return handler_; }
- stdcxx::shared_ptr<Client> createClient() {
+ std::shared_ptr<Client> createClient() {
typedef typename ServiceTraits_::Protocol Protocol;
- stdcxx::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port_));
- stdcxx::shared_ptr<Transport_> transport(new Transport_(socket));
- stdcxx::shared_ptr<Protocol> protocol(new Protocol(transport));
+ std::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port_));
+ std::shared_ptr<Transport_> transport(new Transport_(socket));
+ std::shared_ptr<Protocol> protocol(new Protocol(transport));
transport->open();
- stdcxx::shared_ptr<Client> client(new Client(protocol));
+ std::shared_ptr<Client> client(new Client(protocol));
return client;
}
private:
uint16_t port_;
- stdcxx::shared_ptr<EventLog> log_;
- stdcxx::shared_ptr<Handler> handler_;
- stdcxx::shared_ptr<Processor> processor_;
- stdcxx::shared_ptr<TTransportFactory> transportFactory_;
- stdcxx::shared_ptr<TProtocolFactory> protocolFactory_;
- stdcxx::shared_ptr<TServerEventHandler> serverEventHandler_;
- stdcxx::shared_ptr<TProcessorEventHandler> processorEventHandler_;
+ std::shared_ptr<EventLog> log_;
+ std::shared_ptr<Handler> handler_;
+ std::shared_ptr<Processor> processor_;
+ std::shared_ptr<TTransportFactory> transportFactory_;
+ std::shared_ptr<TProtocolFactory> protocolFactory_;
+ std::shared_ptr<TServerEventHandler> serverEventHandler_;
+ std::shared_ptr<TProcessorEventHandler> processorEventHandler_;
};
/**
* Check that there are no more events in the log
*/
-void checkNoEvents(const stdcxx::shared_ptr<EventLog>& log) {
+void checkNoEvents(const std::shared_ptr<EventLog>& log) {
// Wait for an event with a very short timeout period. We don't expect
// anything to be present, so we will normally wait for the full timeout.
// On the other hand, a non-zero timeout is nice since it does give a short
@@ -299,7 +299,7 @@
*
* Returns the connection ID allocated by the server.
*/
-uint32_t checkNewConnEvents(const stdcxx::shared_ptr<EventLog>& log) {
+uint32_t checkNewConnEvents(const std::shared_ptr<EventLog>& log) {
// Check for an ET_CONN_CREATED event
Event event = log->waitForEvent(2500);
BOOST_CHECK_EQUAL(EventLog::ET_CONN_CREATED, event.type);
@@ -314,7 +314,7 @@
/**
* Check for the events that should be logged when a connection is closed.
*/
-void checkCloseEvents(const stdcxx::shared_ptr<EventLog>& log, uint32_t connId) {
+void checkCloseEvents(const std::shared_ptr<EventLog>& log, uint32_t connId) {
// Check for an ET_CONN_DESTROYED event
Event event = log->waitForEvent();
BOOST_CHECK_EQUAL(EventLog::ET_CONN_DESTROYED, event.type);
@@ -332,7 +332,7 @@
*
* Returns the call ID allocated by the server.
*/
-uint32_t checkCallHandlerEvents(const stdcxx::shared_ptr<EventLog>& log,
+uint32_t checkCallHandlerEvents(const std::shared_ptr<EventLog>& log,
uint32_t connId,
EventType callType,
const string& callName) {
@@ -369,7 +369,7 @@
/**
* Check for the events that should be after a handler returns.
*/
-void checkCallPostHandlerEvents(const stdcxx::shared_ptr<EventLog>& log,
+void checkCallPostHandlerEvents(const std::shared_ptr<EventLog>& log,
uint32_t connId,
uint32_t callId,
const string& callName) {
@@ -409,7 +409,7 @@
*
* Returns the call ID allocated by the server.
*/
-uint32_t checkCallEvents(const stdcxx::shared_ptr<EventLog>& log,
+uint32_t checkCallEvents(const std::shared_ptr<EventLog>& log,
uint32_t connId,
EventType callType,
const string& callName) {
@@ -424,8 +424,8 @@
*/
template <typename State_>
-void testParentService(const stdcxx::shared_ptr<State_>& state) {
- stdcxx::shared_ptr<typename State_::Client> client = state->createClient();
+void testParentService(const std::shared_ptr<State_>& state) {
+ std::shared_ptr<typename State_::Client> client = state->createClient();
int32_t gen = client->getGeneration();
int32_t newGen = client->incrementGeneration();
@@ -446,8 +446,8 @@
}
template <typename State_>
-void testChildService(const stdcxx::shared_ptr<State_>& state) {
- stdcxx::shared_ptr<typename State_::Client> client = state->createClient();
+void testChildService(const std::shared_ptr<State_>& state) {
+ std::shared_ptr<typename State_::Client> client = state->createClient();
// Test calling some of the parent methids via the a child client
int32_t gen = client->getGeneration();
@@ -468,7 +468,7 @@
typedef ServiceState<ServerTraits, ParentServiceTraits<TemplateTraits> > State;
// Start the server
- stdcxx::shared_ptr<State> state(new State);
+ std::shared_ptr<State> state(new State);
ServerThread serverThread(state, true);
testParentService(state);
@@ -479,7 +479,7 @@
typedef ServiceState<ServerTraits, ChildServiceTraits<TemplateTraits> > State;
// Start the server
- stdcxx::shared_ptr<State> state(new State);
+ std::shared_ptr<State> state(new State);
ServerThread serverThread(state, true);
testParentService(state);
@@ -502,10 +502,10 @@
TBufferedTransport> State;
// Start the server
- stdcxx::shared_ptr<State> state(new State);
+ std::shared_ptr<State> state(new State);
ServerThread serverThread(state, true);
- const stdcxx::shared_ptr<EventLog>& log = state->getLog();
+ const std::shared_ptr<EventLog>& log = state->getLog();
// Make sure we're at the end of the log
checkNoEvents(log);
@@ -514,7 +514,7 @@
// Make sure createContext() is called after a connection has been
// established. We open a plain socket instead of creating a client.
- stdcxx::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", state->getPort()));
+ std::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", state->getPort()));
socket->open();
// Make sure the proper events occurred after a new connection
@@ -524,7 +524,7 @@
// can test the timing for the preRead() call.
string requestName = "getDataWait";
string eventName = "ParentService.getDataWait";
- int32_t seqid = int32_t(time(NULL));
+ auto seqid = int32_t(time(nullptr));
TBinaryProtocol protocol(socket);
protocol.writeMessageBegin(requestName, T_CALL, seqid);
socket->flush();
@@ -635,19 +635,19 @@
typedef ServiceState<ServerTraits, ChildServiceTraits<TemplateTraits> > State;
// Start the server
- stdcxx::shared_ptr<State> state(new State);
+ std::shared_ptr<State> state(new State);
ServerThread serverThread(state, true);
- const stdcxx::shared_ptr<EventLog>& log = state->getLog();
+ const std::shared_ptr<EventLog>& log = state->getLog();
// Create a client
- stdcxx::shared_ptr<typename State::Client> client1 = state->createClient();
+ std::shared_ptr<typename State::Client> client1 = state->createClient();
// Make sure the expected events were logged
uint32_t client1Id = checkNewConnEvents(log);
// Create a second client
- stdcxx::shared_ptr<typename State::Client> client2 = state->createClient();
+ std::shared_ptr<typename State::Client> client2 = state->createClient();
// Make sure the expected events were logged
uint32_t client2Id = checkNewConnEvents(log);
@@ -683,13 +683,13 @@
typedef ServiceState<ServerTraits, ChildServiceTraits<TemplateTraits> > State;
// Start the server
- stdcxx::shared_ptr<State> state(new State);
+ std::shared_ptr<State> state(new State);
ServerThread serverThread(state, true);
- const stdcxx::shared_ptr<EventLog>& log = state->getLog();
+ const std::shared_ptr<EventLog>& log = state->getLog();
// Create a client
- stdcxx::shared_ptr<typename State::Client> client = state->createClient();
+ std::shared_ptr<typename State::Client> client = state->createClient();
uint32_t connId = checkNewConnEvents(log);
// Make a oneway call
@@ -735,13 +735,13 @@
typedef ServiceState<ServerTraits, ChildServiceTraits<TemplateTraits> > State;
// Start the server
- stdcxx::shared_ptr<State> state(new State);
+ std::shared_ptr<State> state(new State);
ServerThread serverThread(state, true);
- const stdcxx::shared_ptr<EventLog>& log = state->getLog();
+ const std::shared_ptr<EventLog>& log = state->getLog();
// Create a client
- stdcxx::shared_ptr<typename State::Client> client = state->createClient();
+ std::shared_ptr<typename State::Client> client = state->createClient();
uint32_t connId = checkNewConnEvents(log);
// Send the exceptionWait() call
@@ -790,13 +790,13 @@
typedef ServiceState<ServerTraits, ChildServiceTraits<TemplateTraits> > State;
// Start the server
- stdcxx::shared_ptr<State> state(new State);
+ std::shared_ptr<State> state(new State);
ServerThread serverThread(state, true);
- const stdcxx::shared_ptr<EventLog>& log = state->getLog();
+ const std::shared_ptr<EventLog>& log = state->getLog();
// Create a client
- stdcxx::shared_ptr<typename State::Client> client = state->createClient();
+ std::shared_ptr<typename State::Client> client = state->createClient();
uint32_t connId = checkNewConnEvents(log);
// Send the unexpectedExceptionWait() call
diff --git a/lib/cpp/test/processor/ServerThread.cpp b/lib/cpp/test/processor/ServerThread.cpp
index e752d5e..b050500 100644
--- a/lib/cpp/test/processor/ServerThread.cpp
+++ b/lib/cpp/test/processor/ServerThread.cpp
@@ -21,7 +21,7 @@
#include "ServerThread.h"
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/concurrency/ThreadManager.h>
#include <thrift/server/TThreadPoolServer.h>
#include <thrift/transport/TBufferTransports.h>
@@ -38,7 +38,7 @@
helper_.reset(new Helper(this));
// Start the other thread
- concurrency::PlatformThreadFactory threadFactory;
+ concurrency::ThreadFactory threadFactory;
threadFactory.setDetached(false);
thread_ = threadFactory.newThread(helper_);
@@ -130,7 +130,7 @@
serverState_->bindSuccessful(port_);
// Set the real server event handler (replacing ourself)
- stdcxx::shared_ptr<server::TServerEventHandler> serverEventHandler
+ std::shared_ptr<server::TServerEventHandler> serverEventHandler
= serverState_->getServerEventHandler();
server_->setServerEventHandler(serverEventHandler);
diff --git a/lib/cpp/test/processor/ServerThread.h b/lib/cpp/test/processor/ServerThread.h
index 21c3b60..9cca2d6 100644
--- a/lib/cpp/test/processor/ServerThread.h
+++ b/lib/cpp/test/processor/ServerThread.h
@@ -35,7 +35,7 @@
*/
class ServerState {
public:
- virtual ~ServerState() {}
+ virtual ~ServerState() = default;
/**
* Create a server to listen on the specified port.
@@ -43,7 +43,7 @@
* If the server returned fails to bind to the specified port when serve() is
* called on it, createServer() may be called again on a different port.
*/
- virtual stdcxx::shared_ptr<server::TServer> createServer(uint16_t port) = 0;
+ virtual std::shared_ptr<server::TServer> createServer(uint16_t port) = 0;
/**
* Get the TServerEventHandler to set on the server.
@@ -52,8 +52,8 @@
* start serving traffic. It is invoked from the server thread, rather than
* the main thread.
*/
- virtual stdcxx::shared_ptr<server::TServerEventHandler> getServerEventHandler() {
- return stdcxx::shared_ptr<server::TServerEventHandler>();
+ virtual std::shared_ptr<server::TServerEventHandler> getServerEventHandler() {
+ return std::shared_ptr<server::TServerEventHandler>();
}
/**
@@ -70,7 +70,7 @@
*/
class ServerThread {
public:
- ServerThread(const stdcxx::shared_ptr<ServerState>& state, bool autoStart)
+ ServerThread(const std::shared_ptr<ServerState>& state, bool autoStart)
: port_(0),
running_(false),
serving_(false),
@@ -105,9 +105,9 @@
public:
Helper(ServerThread* serverThread) : serverThread_(serverThread) {}
- void run() { serverThread_->run(); }
+ void run() override { serverThread_->run(); }
- void preServe() { serverThread_->preServe(); }
+ void preServe() override { serverThread_->preServe(); }
private:
ServerThread* serverThread_;
@@ -116,7 +116,7 @@
void run();
void preServe();
- stdcxx::shared_ptr<Helper> helper_;
+ std::shared_ptr<Helper> helper_;
uint16_t port_;
bool running_;
@@ -124,9 +124,9 @@
bool error_;
concurrency::Monitor serverMonitor_;
- stdcxx::shared_ptr<ServerState> serverState_;
- stdcxx::shared_ptr<server::TServer> server_;
- stdcxx::shared_ptr<concurrency::Thread> thread_;
+ std::shared_ptr<ServerState> serverState_;
+ std::shared_ptr<server::TServer> server_;
+ std::shared_ptr<concurrency::Thread> thread_;
};
}
}
diff --git a/lib/cpp/test/qt/TQTcpServerTest.cpp b/lib/cpp/test/qt/TQTcpServerTest.cpp
index 8a327aa..3371a9a 100644
--- a/lib/cpp/test/qt/TQTcpServerTest.cpp
+++ b/lib/cpp/test/qt/TQTcpServerTest.cpp
@@ -8,7 +8,6 @@
#include <QThread>
#ifndef Q_MOC_RUN
- #include "thrift/stdcxx.h"
#include "thrift/protocol/TBinaryProtocol.h"
#include "thrift/async/TAsyncProcessor.h"
#include "thrift/qt/TQTcpServer.h"
@@ -21,25 +20,25 @@
struct AsyncHandler : public test::ParentServiceCobSvIf {
std::vector<std::string> strings;
- virtual void addString(stdcxx::function<void()> cob, const std::string& s) {
+ void addString(std::function<void()> cob, const std::string& s) override {
strings.push_back(s);
cob();
}
- virtual void getStrings(stdcxx::function<void(std::vector<std::string> const& _return)> cob) {
+ void getStrings(std::function<void(std::vector<std::string> const& _return)> cob) override {
cob(strings);
}
// Overrides not used in this test
- virtual void incrementGeneration(stdcxx::function<void(int32_t const& _return)> cob) {}
- virtual void getGeneration(stdcxx::function<void(int32_t const& _return)> cob) {}
- virtual void getDataWait(stdcxx::function<void(std::string const& _return)> cob,
- const int32_t length) {}
- virtual void onewayWait(stdcxx::function<void()> cob) {}
- virtual void exceptionWait(
- stdcxx::function<void()> cob,
- stdcxx::function<void(::apache::thrift::TDelayedException* _throw)> /* exn_cob */,
- const std::string& message) {}
- virtual void unexpectedExceptionWait(stdcxx::function<void()> cob, const std::string& message) {}
+ void incrementGeneration(std::function<void(int32_t const& _return)> cob) override {}
+ void getGeneration(std::function<void(int32_t const& _return)> cob) override {}
+ void getDataWait(std::function<void(std::string const& _return)> cob,
+ const int32_t length) override {}
+ void onewayWait(std::function<void()> cob) override {}
+ void exceptionWait(
+ std::function<void()> cob,
+ std::function<void(::apache::thrift::TDelayedException* _throw)> /* exn_cob */,
+ const std::string& message) override {}
+ void unexpectedExceptionWait(std::function<void()> cob, const std::string& message) override {}
};
class TQTcpServerTest : public QObject {
@@ -51,18 +50,18 @@
void test_communicate();
private:
- stdcxx::shared_ptr<QThread> serverThread;
- stdcxx::shared_ptr<async::TQTcpServer> server;
- stdcxx::shared_ptr<test::ParentServiceClient> client;
+ std::shared_ptr<QThread> serverThread;
+ std::shared_ptr<async::TQTcpServer> server;
+ std::shared_ptr<test::ParentServiceClient> client;
};
void TQTcpServerTest::initTestCase() {
// setup server
- stdcxx::shared_ptr<QTcpServer> serverSocket = stdcxx::make_shared<QTcpServer>();
+ std::shared_ptr<QTcpServer> serverSocket = std::make_shared<QTcpServer>();
server.reset(new async::TQTcpServer(serverSocket,
- stdcxx::make_shared<test::ParentServiceAsyncProcessor>(
- stdcxx::make_shared<AsyncHandler>()),
- stdcxx::make_shared<protocol::TBinaryProtocolFactory>()));
+ std::make_shared<test::ParentServiceAsyncProcessor>(
+ std::make_shared<AsyncHandler>()),
+ std::make_shared<protocol::TBinaryProtocolFactory>()));
QVERIFY(serverSocket->listen(QHostAddress::LocalHost));
int port = serverSocket->serverPort();
QVERIFY(port > 0);
@@ -74,9 +73,9 @@
serverThread->start();
// setup client
- stdcxx::shared_ptr<QTcpSocket> socket = stdcxx::make_shared<QTcpSocket>();
- client.reset(new test::ParentServiceClient(stdcxx::make_shared<protocol::TBinaryProtocol>(
- stdcxx::make_shared<transport::TQIODeviceTransport>(socket))));
+ std::shared_ptr<QTcpSocket> socket = std::make_shared<QTcpSocket>();
+ client.reset(new test::ParentServiceClient(std::make_shared<protocol::TBinaryProtocol>(
+ std::make_shared<transport::TQIODeviceTransport>(socket))));
socket->connectToHost(QHostAddress::LocalHost, port);
QVERIFY(socket->waitForConnected());
}
diff --git a/lib/csharp/Makefile.am b/lib/csharp/Makefile.am
index be49d5e..cc2bbc9 100644
--- a/lib/csharp/Makefile.am
+++ b/lib/csharp/Makefile.am
@@ -92,9 +92,12 @@
Thrift.45.dll: $(THRIFTCODE)
$(CSC) $(CSC_DEFINES) -out:$@ -target:library -reference:System.Web $(THRIFTCODE)
-clean-local:
- $(RM) Thrift.dll \
- $(RM) Thrift.45.dll
+CLEANFILES = \
+ Thrift.dll \
+ Thrift.45.dll
+
+DISTCLEANFILES = \
+ Makefile.in
EXTRA_DIST = \
$(THRIFTCODE) \
diff --git a/lib/csharp/README.md b/lib/csharp/README.md
index b7dc5de..5fc14cb 100644
--- a/lib/csharp/README.md
+++ b/lib/csharp/README.md
@@ -1,5 +1,11 @@
Thrift C# Software Library
+Deprecation notice
+=======
+
+Per [THRIFT-4723](https://issues.apache.org/jira/browse/THRIFT-4723), both CSharp and Netcore targets are deprecated
+and will be removed with the next release. Migrate to the [NetStd language target](../netstd/README.md) instead.
+
License
=======
diff --git a/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs b/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
index 043a6fa..6e99dd9 100644
--- a/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
+++ b/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
@@ -56,5 +56,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.12.1.*")]
-[assembly: AssemblyFileVersion("0.12.1.*")]
+[assembly: AssemblyVersion("0.13.0.*")]
+[assembly: AssemblyFileVersion("0.13.0.*")]
diff --git a/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj b/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj
index c2b631a..f4a26de 100644
--- a/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj
+++ b/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj
@@ -45,7 +45,7 @@
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>0.12.1.%2a</ApplicationVersion>
+ <ApplicationVersion>0.13.0.0</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
diff --git a/lib/csharp/src/Properties/AssemblyInfo.cs b/lib/csharp/src/Properties/AssemblyInfo.cs
index 3511b5f..ace0310 100644
--- a/lib/csharp/src/Properties/AssemblyInfo.cs
+++ b/lib/csharp/src/Properties/AssemblyInfo.cs
@@ -51,5 +51,5 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("0.12.1.1")]
-[assembly: AssemblyFileVersion("0.12.1.1")]
+[assembly: AssemblyVersion("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/lib/csharp/src/Protocol/TProtocolException.cs b/lib/csharp/src/Protocol/TProtocolException.cs
index c0f007e..7bef236 100644
--- a/lib/csharp/src/Protocol/TProtocolException.cs
+++ b/lib/csharp/src/Protocol/TProtocolException.cs
@@ -42,8 +42,8 @@
{
}
- public TProtocolException(int type)
- : base()
+ public TProtocolException(int type, Exception inner = null)
+ : base(string.Empty, inner)
{
type_ = type;
}
diff --git a/lib/csharp/src/TException.cs b/lib/csharp/src/TException.cs
index aa9a210..b9fae6e 100644
--- a/lib/csharp/src/TException.cs
+++ b/lib/csharp/src/TException.cs
@@ -31,7 +31,7 @@
{
}
- public TException(string message, Exception inner)
+ public TException(string message, Exception inner = null)
: base(message, inner)
{
}
diff --git a/lib/csharp/src/Thrift.45.csproj b/lib/csharp/src/Thrift.45.csproj
index 455916f..4e28b25 100644
--- a/lib/csharp/src/Thrift.45.csproj
+++ b/lib/csharp/src/Thrift.45.csproj
@@ -31,7 +31,7 @@
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
+ <DebugType>portable</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;NET45</DefineConstants>
@@ -39,7 +39,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
+ <DebugType>portable</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;NET45</DefineConstants>
diff --git a/lib/csharp/src/Thrift.csproj b/lib/csharp/src/Thrift.csproj
index d28f7dc..a1a37ae 100644
--- a/lib/csharp/src/Thrift.csproj
+++ b/lib/csharp/src/Thrift.csproj
@@ -45,26 +45,27 @@
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>0.12.1.%2a</ApplicationVersion>
+ <ApplicationVersion>0.13.0.0</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
+ <DebugType>portable</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
+ <DebugType>portable</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
+ <DefineConstants>
+ </DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
diff --git a/lib/csharp/src/Transport/THttpClient.cs b/lib/csharp/src/Transport/THttpClient.cs
index 667fc25..986799c 100644
--- a/lib/csharp/src/Transport/THttpClient.cs
+++ b/lib/csharp/src/Transport/THttpClient.cs
@@ -1,4 +1,4 @@
-/**
+/**
* 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
@@ -43,6 +43,7 @@
private int readTimeout = 30000;
private IDictionary<string, string> customHeaders = new Dictionary<string, string>();
+ private string userAgent = "C#/THttpClient";
#if !SILVERLIGHT
private IWebProxy proxy = WebRequest.DefaultWebProxy;
@@ -52,12 +53,22 @@
: this(u, Enumerable.Empty<X509Certificate>())
{
}
+ public THttpClient(Uri u, string userAgent)
+ : this(u, userAgent, Enumerable.Empty<X509Certificate>())
+ {
+ }
public THttpClient(Uri u, IEnumerable<X509Certificate> certificates)
{
uri = u;
this.certificates = (certificates ?? Enumerable.Empty<X509Certificate>()).ToArray();
}
+ public THttpClient(Uri u, string userAgent, IEnumerable<X509Certificate> certificates)
+ {
+ uri = u;
+ this.userAgent = userAgent;
+ this.certificates = (certificates ?? Enumerable.Empty<X509Certificate>()).ToArray();
+ }
public int ConnectTimeout
{
@@ -271,7 +282,7 @@
// Make the request
connection.ContentType = "application/x-thrift";
connection.Accept = "application/x-thrift";
- connection.UserAgent = "C#/THttpClient";
+ connection.UserAgent = userAgent;
connection.Method = "POST";
#if !SILVERLIGHT
connection.ProtocolVersion = HttpVersion.Version10;
diff --git a/lib/csharp/src/Transport/TTLSSocket.cs b/lib/csharp/src/Transport/TTLSSocket.cs
index fd019c3..06286dc 100644
--- a/lib/csharp/src/Transport/TTLSSocket.cs
+++ b/lib/csharp/src/Transport/TTLSSocket.cs
@@ -295,7 +295,33 @@
InitSocket();
}
- client.Connect(host, port);
+ if (timeout == 0) // no timeout -> infinite
+ {
+ client.Connect(host, port);
+ }
+ else // we have a timeout -> use it
+ {
+ ConnectHelper hlp = new ConnectHelper(client);
+ IAsyncResult asyncres = client.BeginConnect(host, port, new AsyncCallback(ConnectCallback), hlp);
+ bool bConnected = asyncres.AsyncWaitHandle.WaitOne(timeout) && client.Connected;
+ if (!bConnected)
+ {
+ lock (hlp.Mutex)
+ {
+ if (hlp.CallbackDone)
+ {
+ asyncres.AsyncWaitHandle.Close();
+ client.Close();
+ }
+ else
+ {
+ hlp.DoCleanup = true;
+ client = null;
+ }
+ }
+ throw new TTransportException(TTransportException.ExceptionType.TimedOut, "Connect timed out");
+ }
+ }
setupTLS();
}
@@ -348,6 +374,54 @@
inputStream = this.secureStream;
outputStream = this.secureStream;
}
+
+ static void ConnectCallback(IAsyncResult asyncres)
+ {
+ ConnectHelper hlp = asyncres.AsyncState as ConnectHelper;
+ lock (hlp.Mutex)
+ {
+ hlp.CallbackDone = true;
+
+ try
+ {
+ if (hlp.Client.Client != null)
+ hlp.Client.EndConnect(asyncres);
+ }
+ catch (Exception)
+ {
+ // catch that away
+ }
+
+ if (hlp.DoCleanup)
+ {
+ try
+ {
+ asyncres.AsyncWaitHandle.Close();
+ }
+ catch (Exception) { }
+
+ try
+ {
+ if (hlp.Client is IDisposable)
+ ((IDisposable)hlp.Client).Dispose();
+ }
+ catch (Exception) { }
+ hlp.Client = null;
+ }
+ }
+ }
+
+ private class ConnectHelper
+ {
+ public object Mutex = new object();
+ public bool DoCleanup = false;
+ public bool CallbackDone = false;
+ public TcpClient Client;
+ public ConnectHelper(TcpClient client)
+ {
+ Client = client;
+ }
+ }
/// <summary>
/// Closes the SSL Socket
diff --git a/lib/csharp/test/Multiplex/Client/MultiplexClient.csproj b/lib/csharp/test/Multiplex/Client/MultiplexClient.csproj
index 2e96f55..09d20f5 100644
--- a/lib/csharp/test/Multiplex/Client/MultiplexClient.csproj
+++ b/lib/csharp/test/Multiplex/Client/MultiplexClient.csproj
@@ -46,7 +46,7 @@
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>0.12.1.%2a</ApplicationVersion>
+ <ApplicationVersion>0.13.0.0</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
diff --git a/lib/csharp/test/Multiplex/Client/Properties/AssemblyInfo.cs b/lib/csharp/test/Multiplex/Client/Properties/AssemblyInfo.cs
index 41ea386..0b65c1e 100644
--- a/lib/csharp/test/Multiplex/Client/Properties/AssemblyInfo.cs
+++ b/lib/csharp/test/Multiplex/Client/Properties/AssemblyInfo.cs
@@ -51,5 +51,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.12.1.0")]
-[assembly: AssemblyFileVersion("0.12.1.0")]
+[assembly: AssemblyVersion("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/lib/csharp/test/Multiplex/Makefile.am b/lib/csharp/test/Multiplex/Makefile.am
index 57253d6..9c1f1b8 100644
--- a/lib/csharp/test/Multiplex/Makefile.am
+++ b/lib/csharp/test/Multiplex/Makefile.am
@@ -41,8 +41,19 @@
MultiplexServer.exe: Server/Multiplex.Test.Server.cs ThriftImpl.dll
$(CSC) $(CSC_DEFINES) -out:$@ -reference:../../Thrift.dll -reference:ThriftImpl.dll $<
+CLEANFILES = \
+ MultiplexClient.exe \
+ MultiplexServer.exe \
+ ThriftImpl.dll
+
+DISTCLEANFILES = \
+ Makefile.in
+
clean-local:
- $(RM) -rf gen-csharp *.exe *.dll
+ $(RM) -rf gen-csharp
+
+dist-hook:
+ $(RM) -r $(distdir)/gen-csharp/
TESTPORT = 9501
check-local: MultiplexServer.exe MultiplexClient.exe
diff --git a/lib/csharp/test/Multiplex/Server/MultiplexServer.csproj b/lib/csharp/test/Multiplex/Server/MultiplexServer.csproj
index bd4e45a..23d3253 100644
--- a/lib/csharp/test/Multiplex/Server/MultiplexServer.csproj
+++ b/lib/csharp/test/Multiplex/Server/MultiplexServer.csproj
@@ -46,7 +46,7 @@
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>0.12.1.%2a</ApplicationVersion>
+ <ApplicationVersion>0.13.0.0</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
diff --git a/lib/csharp/test/Multiplex/Server/Properties/AssemblyInfo.cs b/lib/csharp/test/Multiplex/Server/Properties/AssemblyInfo.cs
index 1efbf12..2b8a6af 100644
--- a/lib/csharp/test/Multiplex/Server/Properties/AssemblyInfo.cs
+++ b/lib/csharp/test/Multiplex/Server/Properties/AssemblyInfo.cs
@@ -51,5 +51,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.12.1.0")]
-[assembly: AssemblyFileVersion("0.12.1.0")]
+[assembly: AssemblyVersion("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs b/lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs
index 0254766..b812aaf 100644
--- a/lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs
+++ b/lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs
@@ -49,5 +49,5 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("0.12.1.0")]
-[assembly: AssemblyFileVersion("0.12.1.0")]
+[assembly: AssemblyVersion("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/lib/d/Makefile.am b/lib/d/Makefile.am
index 2a81218..4787e0a 100644
--- a/lib/d/Makefile.am
+++ b/lib/d/Makefile.am
@@ -141,9 +141,13 @@
install-exec-local:
$(INSTALL_PROGRAM) $(all_targets) $(DESTDIR)$(libdir)
-
clean-local:
- $(RM) -rf docs $(D_LIB_NAME) $(D_EVENT_LIB_NAME) $(D_SSL_LIB_NAME) unittest
+ $(RM) -r docs
+ $(RM) $(D_LIB_NAME)
+ $(RM) $(D_EVENT_LIB_NAME)
+ $(RM) $(D_SSL_LIB_NAME)
+ $(RM) -r test/gen-d
+ $(RM) -r unittest
#
diff --git a/lib/d/src/thrift/base.d b/lib/d/src/thrift/base.d
index f15d2d2..150c3da 100644
--- a/lib/d/src/thrift/base.d
+++ b/lib/d/src/thrift/base.d
@@ -50,7 +50,7 @@
/// The Thrift version string, used for informative purposes.
// Note: This is currently hardcoded, but will likely be filled in by the build
// system in future versions.
-enum VERSION = "0.12.1";
+enum VERSION = "0.13.0";
/**
* Functions used for logging inside Thrift.
diff --git a/lib/dart/LICENSE_HEADER b/lib/dart/LICENSE
similarity index 100%
rename from lib/dart/LICENSE_HEADER
rename to lib/dart/LICENSE
diff --git a/lib/dart/Makefile.am b/lib/dart/Makefile.am
index ab6ddc0..373a883 100644
--- a/lib/dart/Makefile.am
+++ b/lib/dart/Makefile.am
@@ -22,12 +22,18 @@
clean-local:
$(RM) -r .pub
- find . -type d -name "packages" | xargs $(RM) -r
+ find . -type d -name ".dart_tool" | xargs $(RM) -r
find . -type f -name ".packages" | xargs $(RM)
- find . -type f -name "pubspec.lock" | xargs $(RM)
+ find . -type d -name "packages" | xargs $(RM) -r
check-local: all
+dist-hook:
+ $(RM) -r $(distdir)/.pub
+ find $(distdir) -type d -name ".dart_tool" | xargs $(RM) -r
+ find $(distdir) -type f -name ".packages" | xargs $(RM)
+ find $(distdir) -type d -name "packages" | xargs $(RM) -r
+
EXTRA_DIST = \
.analysis_options
diff --git a/lib/dart/README.md b/lib/dart/README.md
index 2be168b..4c30291 100644
--- a/lib/dart/README.md
+++ b/lib/dart/README.md
@@ -23,4 +23,4 @@
Using Thrift with Dart
====================
-Dart 1.12.0 or newer is required
+Dart 1.24.3 or newer is required
diff --git a/lib/dart/lib/src/browser/t_web_socket.dart b/lib/dart/lib/src/browser/t_web_socket.dart
index 17693b3..dac9ffd 100644
--- a/lib/dart/lib/src/browser/t_web_socket.dart
+++ b/lib/dart/lib/src/browser/t_web_socket.dart
@@ -18,7 +18,7 @@
library thrift.src.browser;
import 'dart:async';
-import 'dart:convert' show BASE64;
+import 'package:dart2_constant/convert.dart' show base64;
import 'dart:html' show CloseEvent;
import 'dart:html' show Event;
import 'dart:html' show MessageEvent;
@@ -90,7 +90,7 @@
void _sendRequests() {
while (isOpen && _requests.isNotEmpty) {
Uint8List data = _requests.removeAt(0);
- _socket.sendString(BASE64.encode(data));
+ _socket.sendString(base64.encode(data));
}
}
@@ -113,8 +113,7 @@
void _onMessage(MessageEvent message) {
try {
- Uint8List data =
- new Uint8List.fromList(BASE64.decode(message.data));
+ Uint8List data = new Uint8List.fromList(base64.decode(message.data));
_onMessageController.add(data);
} on FormatException catch (_) {
var error = new TProtocolError(TProtocolErrorType.INVALID_DATA,
diff --git a/lib/dart/lib/src/console/t_web_socket.dart b/lib/dart/lib/src/console/t_web_socket.dart
index 4ed7284..c938a96 100644
--- a/lib/dart/lib/src/console/t_web_socket.dart
+++ b/lib/dart/lib/src/console/t_web_socket.dart
@@ -18,7 +18,7 @@
library thrift.src.console.t_web_socket;
import 'dart:async';
-import 'dart:convert' show BASE64;
+import 'package:dart2_constant/convert.dart' show base64;
import 'dart:io';
import 'dart:typed_data' show Uint8List;
@@ -67,13 +67,12 @@
}
void send(Uint8List data) {
- _socket.add(BASE64.encode(data));
+ _socket.add(base64.encode(data));
}
void _onMessage(String message) {
try {
- Uint8List data =
- new Uint8List.fromList(BASE64.decode(message));
+ Uint8List data = new Uint8List.fromList(base64.decode(message));
_onMessageController.add(data);
} on FormatException catch (_) {
var error = new TProtocolError(TProtocolErrorType.INVALID_DATA,
diff --git a/lib/dart/lib/src/protocol/t_compact_protocol.dart b/lib/dart/lib/src/protocol/t_compact_protocol.dart
index 72d7641..ee8094f 100644
--- a/lib/dart/lib/src/protocol/t_compact_protocol.dart
+++ b/lib/dart/lib/src/protocol/t_compact_protocol.dart
@@ -187,7 +187,7 @@
void writeDouble(double d) {
if (d == null) d = 0.0;
- tempBD.setFloat64(0, d, Endianness.LITTLE_ENDIAN);
+ tempBD.setFloat64(0, d, Endianness.little);
transport.write(tempBD.buffer.asUint8List(), 0, 8);
}
@@ -364,7 +364,7 @@
double readDouble() {
transport.readAll(tempList, 0, 8);
- return tempList.buffer.asByteData().getFloat64(0, Endianness.LITTLE_ENDIAN);
+ return tempList.buffer.asByteData().getFloat64(0, Endianness.little);
}
String readString() {
diff --git a/lib/dart/lib/src/protocol/t_json_protocol.dart b/lib/dart/lib/src/protocol/t_json_protocol.dart
index 7fbb7c4..180568d 100644
--- a/lib/dart/lib/src/protocol/t_json_protocol.dart
+++ b/lib/dart/lib/src/protocol/t_json_protocol.dart
@@ -155,8 +155,8 @@
_context.write();
transport.writeAll(_Constants.QUOTE_BYTES);
- String base64 = BASE64.encode(bytes);
- transport.writeAll(utf8Codec.encode(base64));
+ String base64text = base64.encode(bytes);
+ transport.writeAll(utf8Codec.encode(base64text));
transport.writeAll(_Constants.QUOTE_BYTES);
}
@@ -421,9 +421,9 @@
Uint8List _readJsonBase64() {
// convert UTF-8 bytes of a Base 64 encoded string to binary bytes
Uint8List base64Bytes = _readJsonString();
- String base64 = utf8Codec.decode(base64Bytes);
+ String base64text = utf8Codec.decode(base64Bytes);
- return new Uint8List.fromList(BASE64.decode(base64));
+ return new Uint8List.fromList(base64.decode(base64text));
}
void _readJsonObjectStart() {
diff --git a/lib/dart/lib/src/serializer/t_deserializer.dart b/lib/dart/lib/src/serializer/t_deserializer.dart
index ed1d139..aefbee2 100644
--- a/lib/dart/lib/src/serializer/t_deserializer.dart
+++ b/lib/dart/lib/src/serializer/t_deserializer.dart
@@ -26,7 +26,7 @@
this.transport = new TBufferedTransport();
if (protocolFactory == null) {
- protocolFactory = new TBinaryProtocolFactory();
+ protocolFactory = new TBinaryProtocolFactory();
}
this.protocol = protocolFactory.getProtocol(this.transport);
@@ -41,8 +41,8 @@
}
void readString(TBase base, String data) {
- transport.writeAll(BASE64.decode(data));
+ transport.writeAll(base64.decode(data));
transport.flush();
base.read(protocol);
diff --git a/lib/dart/lib/src/serializer/t_serializer.dart b/lib/dart/lib/src/serializer/t_serializer.dart
index 20ddb6d..feec822 100644
--- a/lib/dart/lib/src/serializer/t_serializer.dart
+++ b/lib/dart/lib/src/serializer/t_serializer.dart
@@ -43,6 +43,6 @@
Uint8List bytes = transport.consumeWriteBuffer();
- return BASE64.encode(bytes);
+ return base64.encode(bytes);
}
}
diff --git a/lib/dart/lib/src/transport/t_http_transport.dart b/lib/dart/lib/src/transport/t_http_transport.dart
index aa78e9c..630213f 100644
--- a/lib/dart/lib/src/transport/t_http_transport.dart
+++ b/lib/dart/lib/src/transport/t_http_transport.dart
@@ -44,7 +44,7 @@
}
Future flush() {
- var requestBody = BASE64.encode(consumeWriteBuffer());
+ var requestBody = base64.encode(consumeWriteBuffer());
// Use a sync completer to ensure that the buffer can be read immediately
// after the read buffer is set, and avoid a race condition where another
@@ -56,8 +56,7 @@
.then((response) {
Uint8List data;
try {
- data = new Uint8List.fromList(
- BASE64.decode(response.body));
+ data = new Uint8List.fromList(base64.decode(response.body));
} on FormatException catch (_) {
throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
"Expected a Base 64 encoded string.");
diff --git a/lib/dart/lib/thrift.dart b/lib/dart/lib/thrift.dart
index 3d9bb01..c429d77 100644
--- a/lib/dart/lib/thrift.dart
+++ b/lib/dart/lib/thrift.dart
@@ -19,11 +19,12 @@
import 'dart:async';
import 'dart:collection';
-import 'dart:convert' show Utf8Codec, BASE64;
+import 'dart:convert' show Utf8Codec;
import 'dart:typed_data' show ByteData;
-import 'dart:typed_data' show Endianness;
import 'dart:typed_data' show Uint8List;
+import 'package:dart2_constant/convert.dart' show base64;
+import 'package:dart2_constant/typed_data.dart' show Endianness;
import 'package:fixnum/fixnum.dart';
import 'package:http/http.dart' show Client;
import 'package:logging/logging.dart';
diff --git a/lib/dart/pubspec.yaml b/lib/dart/pubspec.yaml
index 4f205eb..f406b99 100644
--- a/lib/dart/pubspec.yaml
+++ b/lib/dart/pubspec.yaml
@@ -16,7 +16,7 @@
# under the License.
name: thrift
-version: 0.12.1
+version: 0.13.0
description: >
A Dart library for Apache Thrift
author: Apache Thrift Developers <dev@thrift.apache.org>
@@ -24,20 +24,15 @@
documentation: http://thrift.apache.org
environment:
- sdk: ">=1.13.0 <2.0.0"
+ sdk: ">=1.24.3 <3.0.0"
dependencies:
+ dart2_constant: ^1.0.0
fixnum: ^0.10.2
http: ^0.11.3
logging: ^0.11.0
dev_dependencies:
- # test
- mockito: ^1.0.0
- test: ^0.12.0
-
- # dart_dev - https://github.com/Workiva/dart_dev
- dart_dev: ^1.5.0
- coverage: ^0.7.3
- dart_style: ">=0.2.4 <0.3.0"
- dartdoc: ^0.9.0
+ dart_dev: ^2.0.0
+ mockito: ">=2.2.2 <4.0.0"
+ test: ">=0.12.30 <2.0.0"
diff --git a/lib/dart/test/protocol/t_protocol_test.dart b/lib/dart/test/protocol/t_protocol_test.dart
index 0e6cde5..dc63dbb 100644
--- a/lib/dart/test/protocol/t_protocol_test.dart
+++ b/lib/dart/test/protocol/t_protocol_test.dart
@@ -18,9 +18,9 @@
library thrift.test.transport.t_json_protocol_test;
import 'dart:async';
-import 'dart:convert' show UTF8;
import 'dart:typed_data' show Uint8List;
+import 'package:dart2_constant/convert.dart' show utf8;
import 'package:test/test.dart';
import 'package:thrift/thrift.dart';
@@ -362,7 +362,7 @@
UTF-8: 0xF0 0x9D 0x84 0x9E
UTF-16: 0xD834 0xDD1E
*/
- var buffer = UTF8.encode(r'"\u0001\u0e01 \ud834\udd1e"');
+ var buffer = utf8.encode(r'"\u0001\u0e01 \ud834\udd1e"');
var transport = new TBufferedTransport();
transport.writeAll(buffer);
@@ -372,7 +372,7 @@
var subject = protocol.readString();
expect(subject,
- UTF8.decode([0x01, 0xE0, 0xB8, 0x81, 0x20, 0xF0, 0x9D, 0x84, 0x9E]));
+ utf8.decode([0x01, 0xE0, 0xB8, 0x81, 0x20, 0xF0, 0x9D, 0x84, 0x9E]));
});
group('shared tests', sharedTests);
diff --git a/lib/dart/test/transport/t_framed_transport_test.dart b/lib/dart/test/transport/t_framed_transport_test.dart
index e072e68..7ab4905 100644
--- a/lib/dart/test/transport/t_framed_transport_test.dart
+++ b/lib/dart/test/transport/t_framed_transport_test.dart
@@ -18,9 +18,9 @@
library thrift.test.transport.t_framed_transport_test;
import 'dart:async';
-import 'dart:convert';
import 'dart:typed_data' show Uint8List;
+import 'package:dart2_constant/convert.dart' show utf8;
import 'package:test/test.dart';
import 'package:thrift/thrift.dart';
@@ -66,14 +66,14 @@
expectNoReadableBytes();
// write first batch of body
- socket.messageController.add(new Uint8List.fromList(UTF8.encode("He")));
+ socket.messageController.add(new Uint8List.fromList(utf8.encode("He")));
// you shouldn't be able to get any bytes from the read,
// because the frame has been consumed internally
expectNoReadableBytes();
// write second batch of body
- socket.messageController.add(new Uint8List.fromList(UTF8.encode("llo!")));
+ socket.messageController.add(new Uint8List.fromList(utf8.encode("llo!")));
// have to wait for the flush to complete,
// because it's only then that the frame is available for reading
@@ -83,7 +83,7 @@
// at this point the frame is complete, so we expect the read to complete
readBytes = transport.read(readBuffer, 0, readBuffer.lengthInBytes);
expect(readBytes, 6);
- expect(readBuffer.sublist(0, 6), UTF8.encode("Hello!"));
+ expect(readBuffer.sublist(0, 6), utf8.encode("Hello!"));
});
test('Test transport reads messages where header is sent in pieces '
@@ -112,14 +112,14 @@
readBytes = expectNoReadableBytes();
// write first batch of body
- socket.messageController.add(new Uint8List.fromList(UTF8.encode("H")));
+ socket.messageController.add(new Uint8List.fromList(utf8.encode("H")));
// you shouldn't be able to get any bytes from the read,
// because the frame has been consumed internally
expectNoReadableBytes();
// write second batch of body
- socket.messageController.add(new Uint8List.fromList(UTF8.encode("i!")));
+ socket.messageController.add(new Uint8List.fromList(utf8.encode("i!")));
// have to wait for the flush to complete,
// because it's only then that the frame is available for reading
@@ -129,7 +129,7 @@
// at this point the frame is complete, so we expect the read to complete
readBytes = transport.read(readBuffer, 0, readBuffer.lengthInBytes);
expect(readBytes, 3);
- expect(readBuffer.sublist(0, 3), UTF8.encode("Hi!"));
+ expect(readBuffer.sublist(0, 3), utf8.encode("Hi!"));
});
});
}
diff --git a/lib/dart/test/transport/t_http_transport_test.dart b/lib/dart/test/transport/t_http_transport_test.dart
index 66f3d05..03ccede 100644
--- a/lib/dart/test/transport/t_http_transport_test.dart
+++ b/lib/dart/test/transport/t_http_transport_test.dart
@@ -19,9 +19,10 @@
import 'dart:async';
import 'dart:convert' show Encoding;
-import 'dart:convert' show Utf8Codec, BASE64;
+import 'dart:convert' show Utf8Codec;
import 'dart:typed_data' show Uint8List;
+import 'package:dart2_constant/convert.dart' show base64;
import 'package:http/http.dart' show BaseRequest;
import 'package:http/http.dart' show Client;
import 'package:http/http.dart' show Response;
@@ -52,15 +53,14 @@
expect(client.postRequest, isNotEmpty);
- var requestText =
- utf8Codec.decode(BASE64.decode(client.postRequest));
+ var requestText = utf8Codec.decode(base64.decode(client.postRequest));
expect(requestText, expectedText);
});
test('Test transport receives response', () async {
var expectedText = 'my response';
var expectedBytes = utf8Codec.encode(expectedText);
- client.postResponse = BASE64.encode(expectedBytes);
+ client.postResponse = base64.encode(expectedBytes);
transport.writeAll(utf8Codec.encode('my request'));
expect(transport.hasReadData, isFalse);
@@ -94,7 +94,7 @@
// prepare a response
transport.writeAll(utf8Codec.encode('request 1'));
- client.postResponse = BASE64.encode(expectedBytes);
+ client.postResponse = base64.encode(expectedBytes);
Future responseReady = transport.flush().then((_) {
var buffer = new Uint8List(expectedBytes.length);
@@ -105,7 +105,7 @@
// prepare a second response
transport.writeAll(utf8Codec.encode('request 2'));
var response2Bytes = utf8Codec.encode('response 2');
- client.postResponse = BASE64.encode(response2Bytes);
+ client.postResponse = base64.encode(response2Bytes);
await transport.flush();
await responseReady;
diff --git a/lib/dart/test/transport/t_socket_transport_test.dart b/lib/dart/test/transport/t_socket_transport_test.dart
index 929ab17..90bffbe 100644
--- a/lib/dart/test/transport/t_socket_transport_test.dart
+++ b/lib/dart/test/transport/t_socket_transport_test.dart
@@ -18,9 +18,11 @@
library thrift.test.transport.t_socket_transport_test;
import 'dart:async';
-import 'dart:convert' show Utf8Codec, BASE64;
+import 'dart:convert' show Utf8Codec;
import 'dart:typed_data' show Uint8List;
+import 'package:dart2_constant/convert.dart' show base64;
+import 'package:dart2_constant/core.dart' as core;
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
import 'package:thrift/thrift.dart';
@@ -30,14 +32,13 @@
final requestText = 'my test request';
final requestBytes = new Uint8List.fromList(utf8Codec.encode(requestText));
- final requestBase64 = BASE64.encode(requestBytes);
+ final requestBase64 = base64.encode(requestBytes);
final responseText = 'response 1';
final responseBytes = new Uint8List.fromList(utf8Codec.encode(responseText));
- final responseBase64 = BASE64.encode(responseBytes);
+ final responseBase64 = base64.encode(responseBytes);
- final framedResponseBase64 =
- BASE64.encode(_getFramedResponse(responseBytes));
+ final framedResponseBase64 = base64.encode(_getFramedResponse(responseBytes));
group('TClientSocketTransport', () {
FakeSocket socket;
@@ -117,7 +118,7 @@
protocolFactory.message = new TMessage('foo', TMessageType.CALL, 123);
transport = new TAsyncClientSocketTransport(
socket, new TMessageReader(protocolFactory),
- responseTimeout: Duration.ZERO);
+ responseTimeout: core.Duration.zero);
await transport.open();
transport.writeAll(requestBytes);
});
@@ -139,7 +140,7 @@
var response2Text = 'response 2';
var response2Bytes =
new Uint8List.fromList(utf8Codec.encode(response2Text));
- var response2Base64 = BASE64.encode(response2Bytes);
+ var response2Base64 = base64.encode(response2Bytes);
protocolFactory.message = new TMessage('foo2', TMessageType.REPLY, 124);
socket.receiveFakeMessage(response2Base64);
@@ -169,7 +170,7 @@
transport = new TFramedTransport(new TAsyncClientSocketTransport(
socket, messageReader,
- responseTimeout: Duration.ZERO));
+ responseTimeout: core.Duration.zero));
await transport.open();
transport.writeAll(requestBytes);
});
@@ -275,11 +276,10 @@
_sendPayload = data;
}
- void receiveFakeMessage(String base64) {
+ void receiveFakeMessage(String base64text) {
if (!isOpen) throw new StateError('The socket is not open');
- var message =
- new Uint8List.fromList(BASE64.decode(base64));
+ var message = new Uint8List.fromList(base64.decode(base64text));
_onMessageController.add(message);
}
}
diff --git a/lib/delphi/src/Thrift.Collections.pas b/lib/delphi/src/Thrift.Collections.pas
index b2206cb..2e13724 100644
--- a/lib/delphi/src/Thrift.Collections.pas
+++ b/lib/delphi/src/Thrift.Collections.pas
@@ -22,7 +22,7 @@
interface
uses
- Generics.Collections, Generics.Defaults, Thrift.Utils;
+ SysUtils, Generics.Collections, Generics.Defaults, Thrift.Utils;
type
@@ -30,11 +30,11 @@
TArray<T> = array of T;
{$IFEND}
- IThriftContainer = interface
- ['{93DEF5A0-D162-461A-AB22-5B4EE0734050}']
- function ToString: string;
+ IThriftContainer = interface( ISupportsToString)
+ ['{E05C0F9D-A4F5-491D-AADA-C926B4BDB6E4}']
end;
+
IThriftDictionary<TKey,TValue> = interface(IThriftContainer)
['{25EDD506-F9D1-4008-A40F-5940364B7E46}']
function GetEnumerator: TEnumerator<TPair<TKey,TValue>>;
@@ -64,7 +64,7 @@
property Values: TDictionary<TKey,TValue>.TValueCollection read GetValues;
end;
- TThriftDictionaryImpl<TKey,TValue> = class( TInterfacedObject, IThriftDictionary<TKey,TValue>)
+ TThriftDictionaryImpl<TKey,TValue> = class( TInterfacedObject, IThriftDictionary<TKey,TValue>, IThriftContainer, ISupportsToString)
private
FDictionaly : TDictionary<TKey,TValue>;
protected
@@ -95,6 +95,7 @@
public
constructor Create(ACapacity: Integer = 0);
destructor Destroy; override;
+ function ToString : string; override;
end;
IThriftList<T> = interface(IThriftContainer)
@@ -140,7 +141,7 @@
property Items[Index: Integer]: T read GetItem write SetItem; default;
end;
- TThriftListImpl<T> = class( TInterfacedObject, IThriftList<T>)
+ TThriftListImpl<T> = class( TInterfacedObject, IThriftList<T>, IThriftContainer, ISupportsToString)
private
FList : TList<T>;
protected
@@ -186,6 +187,7 @@
public
constructor Create;
destructor Destroy; override;
+ function ToString : string; override;
end;
IHashSet<TValue> = interface(IThriftContainer)
@@ -202,7 +204,7 @@
function Remove( const item: TValue ): Boolean;
end;
- THashSetImpl<TValue> = class( TInterfacedObject, IHashSet<TValue>)
+ THashSetImpl<TValue> = class( TInterfacedObject, IHashSet<TValue>, IThriftContainer, ISupportsToString)
private
FDictionary : IThriftDictionary<TValue,Integer>;
FIsReadOnly: Boolean;
@@ -219,6 +221,7 @@
function Remove( const item: TValue ): Boolean;
public
constructor Create;
+ function ToString : string; override;
end;
implementation
@@ -287,6 +290,28 @@
end;
end;
+function THashSetImpl<TValue>.ToString : string;
+var elm : TValue;
+ sb : TThriftStringBuilder;
+ first : Boolean;
+begin
+ sb := TThriftStringBuilder.Create('{');
+ try
+ first := TRUE;
+ for elm in FDictionary.Keys do begin
+ if first
+ then first := FALSE
+ else sb.Append(', ');
+
+ sb.Append( StringUtils<TValue>.ToString(elm));
+ end;
+ sb.Append('}');
+ Result := sb.ToString;
+ finally
+ sb.Free;
+ end;
+end;
+
{ TThriftDictionaryImpl<TKey, TValue> }
procedure TThriftDictionaryImpl<TKey, TValue>.Add(const Key: TKey;
@@ -393,6 +418,32 @@
{$IFEND}
end;
+function TThriftDictionaryImpl<TKey, TValue>.ToString : string;
+var pair : TPair<TKey, TValue>;
+ sb : TThriftStringBuilder;
+ first : Boolean;
+begin
+ sb := TThriftStringBuilder.Create('{');
+ try
+ first := TRUE;
+ for pair in FDictionaly do begin
+ if first
+ then first := FALSE
+ else sb.Append(', ');
+
+ sb.Append( '(');
+ sb.Append( StringUtils<TKey>.ToString(pair.Key));
+ sb.Append(' => ');
+ sb.Append( StringUtils<TValue>.ToString(pair.Value));
+ sb.Append(')');
+ end;
+ sb.Append('}');
+ Result := sb.ToString;
+ finally
+ sb.Free;
+ end;
+end;
+
procedure TThriftDictionaryImpl<TKey, TValue>.TrimExcess;
begin
FDictionaly.TrimExcess;
@@ -611,6 +662,28 @@
{$IFEND}
end;
+function TThriftListImpl<T>.ToString : string;
+var elm : T;
+ sb : TThriftStringBuilder;
+ first : Boolean;
+begin
+ sb := TThriftStringBuilder.Create('{');
+ try
+ first := TRUE;
+ for elm in FList do begin
+ if first
+ then first := FALSE
+ else sb.Append(', ');
+
+ sb.Append( StringUtils<T>.ToString(elm));
+ end;
+ sb.Append('}');
+ Result := sb.ToString;
+ finally
+ sb.Free;
+ end;
+end;
+
procedure TThriftListImpl<T>.TrimExcess;
begin
FList.TrimExcess;
diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas
index 36509ca..609dfc6 100644
--- a/lib/delphi/src/Thrift.Protocol.pas
+++ b/lib/delphi/src/Thrift.Protocol.pas
@@ -29,6 +29,7 @@
Contnrs,
Thrift.Exception,
Thrift.Stream,
+ Thrift.Utils,
Thrift.Collections,
Thrift.Transport;
@@ -111,12 +112,6 @@
function GetProtocol( const trans: ITransport): IProtocol;
end;
- TThriftStringBuilder = class( TStringBuilder)
- public
- function Append(const Value: TBytes): TStringBuilder; overload;
- function Append(const Value: IThriftContainer): TStringBuilder; overload;
- end;
-
TProtocolException = class( TException)
public
const // TODO(jensg): change into enum
@@ -292,9 +287,8 @@
constructor Create( trans: ITransport );
end;
- IBase = interface
- ['{08D9BAA8-5EAA-410F-B50B-AC2E6E5E4155}']
- function ToString: string;
+ IBase = interface( ISupportsToString)
+ ['{AFF6CECA-5200-4540-950E-9B89E0C1C00C}']
procedure Read( const iprot: IProtocol);
procedure Write( const iprot: IProtocol);
end;
@@ -1034,19 +1028,6 @@
inherited HiddenCreate(Msg);
end;
-{ TThriftStringBuilder }
-
-function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder;
-begin
- Result := Append( string( RawByteString(Value)) );
-end;
-
-function TThriftStringBuilder.Append(
- const Value: IThriftContainer): TStringBuilder;
-begin
- Result := Append( Value.ToString );
-end;
-
{ TBinaryProtocolImpl.TFactory }
constructor TBinaryProtocolImpl.TFactory.Create(AStrictRead, AStrictWrite: Boolean);
diff --git a/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas b/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas
new file mode 100644
index 0000000..cdfb541
--- /dev/null
+++ b/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas
@@ -0,0 +1,255 @@
+(*
+ * 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 Thrift.Transport.MsxmlHTTP;
+
+{$I Thrift.Defines.inc}
+{$SCOPEDENUMS ON}
+
+interface
+
+uses
+ Classes,
+ SysUtils,
+ Math,
+ Generics.Collections,
+ {$IFDEF OLD_UNIT_NAMES}
+ ActiveX, msxml,
+ {$ELSE}
+ Winapi.ActiveX, Winapi.msxml,
+ {$ENDIF}
+ Thrift.Collections,
+ Thrift.Transport,
+ Thrift.Exception,
+ Thrift.Utils,
+ Thrift.Stream;
+
+type
+ TMsxmlHTTPClientImpl = class( TTransportImpl, IHTTPClient)
+ private
+ FUri : string;
+ FInputStream : IThriftStream;
+ FOutputStream : IThriftStream;
+ FDnsResolveTimeout : Integer;
+ FConnectionTimeout : Integer;
+ FSendTimeout : Integer;
+ FReadTimeout : Integer;
+ FCustomHeaders : IThriftDictionary<string,string>;
+
+ function CreateRequest: IXMLHTTPRequest;
+ protected
+ function GetIsOpen: Boolean; override;
+ procedure Open(); override;
+ procedure Close(); override;
+ function Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override;
+ procedure Write( const pBuf : Pointer; off, len : Integer); override;
+ procedure Flush; override;
+
+ procedure SetDnsResolveTimeout(const Value: Integer);
+ function GetDnsResolveTimeout: Integer;
+ procedure SetConnectionTimeout(const Value: Integer);
+ function GetConnectionTimeout: Integer;
+ procedure SetSendTimeout(const Value: Integer);
+ function GetSendTimeout: Integer;
+ procedure SetReadTimeout(const Value: Integer);
+ function GetReadTimeout: Integer;
+
+ function GetCustomHeaders: IThriftDictionary<string,string>;
+ procedure SendRequest;
+ property DnsResolveTimeout: Integer read GetDnsResolveTimeout write SetDnsResolveTimeout;
+ property ConnectionTimeout: Integer read GetConnectionTimeout write SetConnectionTimeout;
+ property SendTimeout: Integer read GetSendTimeout write SetSendTimeout;
+ property ReadTimeout: Integer read GetReadTimeout write SetReadTimeout;
+ property CustomHeaders: IThriftDictionary<string,string> read GetCustomHeaders;
+ public
+ constructor Create( const AUri: string);
+ destructor Destroy; override;
+ end;
+
+
+implementation
+
+
+{ TMsxmlHTTPClientImpl }
+
+constructor TMsxmlHTTPClientImpl.Create(const AUri: string);
+begin
+ inherited Create;
+ FUri := AUri;
+
+ // defaults according to MSDN
+ FDnsResolveTimeout := 0; // no timeout
+ FConnectionTimeout := 60 * 1000;
+ FSendTimeout := 30 * 1000;
+ FReadTimeout := 30 * 1000;
+
+ FCustomHeaders := TThriftDictionaryImpl<string,string>.Create;
+ FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
+end;
+
+function TMsxmlHTTPClientImpl.CreateRequest: IXMLHTTPRequest;
+var
+ pair : TPair<string,string>;
+ srvHttp : IServerXMLHTTPRequest;
+begin
+ {$IF CompilerVersion >= 21.0}
+ Result := CoServerXMLHTTP.Create;
+ {$ELSE}
+ Result := CoXMLHTTPRequest.Create;
+ {$IFEND}
+
+ // setting a timeout value to 0 (zero) means "no timeout" for that setting
+ if Supports( result, IServerXMLHTTPRequest, srvHttp)
+ then srvHttp.setTimeouts( DnsResolveTimeout, ConnectionTimeout, SendTimeout, ReadTimeout);
+
+ Result.open('POST', FUri, False, '', '');
+ Result.setRequestHeader( 'Content-Type', 'application/x-thrift');
+ Result.setRequestHeader( 'Accept', 'application/x-thrift');
+ Result.setRequestHeader( 'User-Agent', 'Delphi/IHTTPClient');
+
+ for pair in FCustomHeaders do begin
+ Result.setRequestHeader( pair.Key, pair.Value );
+ end;
+end;
+
+destructor TMsxmlHTTPClientImpl.Destroy;
+begin
+ Close;
+ inherited;
+end;
+
+function TMsxmlHTTPClientImpl.GetDnsResolveTimeout: Integer;
+begin
+ Result := FDnsResolveTimeout;
+end;
+
+procedure TMsxmlHTTPClientImpl.SetDnsResolveTimeout(const Value: Integer);
+begin
+ FDnsResolveTimeout := Value;
+end;
+
+function TMsxmlHTTPClientImpl.GetConnectionTimeout: Integer;
+begin
+ Result := FConnectionTimeout;
+end;
+
+procedure TMsxmlHTTPClientImpl.SetConnectionTimeout(const Value: Integer);
+begin
+ FConnectionTimeout := Value;
+end;
+
+function TMsxmlHTTPClientImpl.GetSendTimeout: Integer;
+begin
+ Result := FSendTimeout;
+end;
+
+procedure TMsxmlHTTPClientImpl.SetSendTimeout(const Value: Integer);
+begin
+ FSendTimeout := Value;
+end;
+
+function TMsxmlHTTPClientImpl.GetReadTimeout: Integer;
+begin
+ Result := FReadTimeout;
+end;
+
+procedure TMsxmlHTTPClientImpl.SetReadTimeout(const Value: Integer);
+begin
+ FReadTimeout := Value;
+end;
+
+function TMsxmlHTTPClientImpl.GetCustomHeaders: IThriftDictionary<string,string>;
+begin
+ Result := FCustomHeaders;
+end;
+
+function TMsxmlHTTPClientImpl.GetIsOpen: Boolean;
+begin
+ Result := True;
+end;
+
+procedure TMsxmlHTTPClientImpl.Open;
+begin
+ FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
+end;
+
+procedure TMsxmlHTTPClientImpl.Close;
+begin
+ FInputStream := nil;
+ FOutputStream := nil;
+end;
+
+procedure TMsxmlHTTPClientImpl.Flush;
+begin
+ try
+ SendRequest;
+ finally
+ FOutputStream := nil;
+ FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
+ ASSERT( FOutputStream <> nil);
+ end;
+end;
+
+function TMsxmlHTTPClientImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer;
+begin
+ if FInputStream = nil then begin
+ raise TTransportExceptionNotOpen.Create('No request has been sent');
+ end;
+
+ try
+ Result := FInputStream.Read( pBuf, buflen, off, len)
+ except
+ on E: Exception
+ do raise TTransportExceptionUnknown.Create(E.Message);
+ end;
+end;
+
+procedure TMsxmlHTTPClientImpl.SendRequest;
+var
+ xmlhttp : IXMLHTTPRequest;
+ ms : TMemoryStream;
+ a : TBytes;
+ len : Integer;
+begin
+ xmlhttp := CreateRequest;
+
+ ms := TMemoryStream.Create;
+ try
+ a := FOutputStream.ToArray;
+ len := Length(a);
+ if len > 0 then begin
+ ms.WriteBuffer( Pointer(@a[0])^, len);
+ end;
+ ms.Position := 0;
+ xmlhttp.send( IUnknown( TStreamAdapter.Create( ms, soReference )));
+ FInputStream := nil;
+ FInputStream := TThriftStreamAdapterCOM.Create( IUnknown( xmlhttp.responseStream) as IStream);
+ finally
+ ms.Free;
+ end;
+end;
+
+procedure TMsxmlHTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer);
+begin
+ FOutputStream.Write( pBuf, off, len);
+end;
+
+
+
+end.
+
diff --git a/lib/delphi/src/Thrift.Transport.WinHTTP.pas b/lib/delphi/src/Thrift.Transport.WinHTTP.pas
new file mode 100644
index 0000000..aac2aea
--- /dev/null
+++ b/lib/delphi/src/Thrift.Transport.WinHTTP.pas
@@ -0,0 +1,335 @@
+(*
+ * 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 Thrift.Transport.WinHTTP;
+
+{$I Thrift.Defines.inc}
+{$SCOPEDENUMS ON}
+
+interface
+
+uses
+ Classes,
+ SysUtils,
+ Math,
+ Generics.Collections,
+ Thrift.Collections,
+ Thrift.Transport,
+ Thrift.Exception,
+ Thrift.Utils,
+ Thrift.WinHTTP,
+ Thrift.Stream;
+
+type
+ TWinHTTPClientImpl = class( TTransportImpl, IHTTPClient)
+ private
+ FUri : string;
+ FInputStream : IThriftStream;
+ FOutputMemoryStream : TMemoryStream;
+ FDnsResolveTimeout : Integer;
+ FConnectionTimeout : Integer;
+ FSendTimeout : Integer;
+ FReadTimeout : Integer;
+ FCustomHeaders : IThriftDictionary<string,string>;
+
+ function CreateRequest: IWinHTTPRequest;
+
+ private type
+ THTTPResponseStream = class( TThriftStreamImpl)
+ private
+ FRequest : IWinHTTPRequest;
+ protected
+ procedure Write( const pBuf : Pointer; offset: Integer; count: Integer); override;
+ function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; override;
+ procedure Open; override;
+ procedure Close; override;
+ procedure Flush; override;
+ function IsOpen: Boolean; override;
+ function ToArray: TBytes; override;
+ public
+ constructor Create( const aRequest : IWinHTTPRequest);
+ destructor Destroy; override;
+ end;
+
+ protected
+ function GetIsOpen: Boolean; override;
+ procedure Open(); override;
+ procedure Close(); override;
+ function Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override;
+ procedure Write( const pBuf : Pointer; off, len : Integer); override;
+ procedure Flush; override;
+
+ procedure SetDnsResolveTimeout(const Value: Integer);
+ function GetDnsResolveTimeout: Integer;
+ procedure SetConnectionTimeout(const Value: Integer);
+ function GetConnectionTimeout: Integer;
+ procedure SetSendTimeout(const Value: Integer);
+ function GetSendTimeout: Integer;
+ procedure SetReadTimeout(const Value: Integer);
+ function GetReadTimeout: Integer;
+
+ function GetCustomHeaders: IThriftDictionary<string,string>;
+ procedure SendRequest;
+ property DnsResolveTimeout: Integer read GetDnsResolveTimeout write SetDnsResolveTimeout;
+ property ConnectionTimeout: Integer read GetConnectionTimeout write SetConnectionTimeout;
+ property SendTimeout: Integer read GetSendTimeout write SetSendTimeout;
+ property ReadTimeout: Integer read GetReadTimeout write SetReadTimeout;
+ property CustomHeaders: IThriftDictionary<string,string> read GetCustomHeaders;
+ public
+ constructor Create( const AUri: string);
+ destructor Destroy; override;
+ end;
+
+implementation
+
+
+{ TWinHTTPClientImpl }
+
+constructor TWinHTTPClientImpl.Create(const AUri: string);
+begin
+ inherited Create;
+ FUri := AUri;
+
+ // defaults according to MSDN
+ FDnsResolveTimeout := 0; // no timeout
+ FConnectionTimeout := 60 * 1000;
+ FSendTimeout := 30 * 1000;
+ FReadTimeout := 30 * 1000;
+
+ FCustomHeaders := TThriftDictionaryImpl<string,string>.Create;
+ FOutputMemoryStream := TMemoryStream.Create;
+end;
+
+destructor TWinHTTPClientImpl.Destroy;
+begin
+ Close;
+ FreeAndNil( FOutputMemoryStream);
+ inherited;
+end;
+
+function TWinHTTPClientImpl.CreateRequest: IWinHTTPRequest;
+var
+ pair : TPair<string,string>;
+ session : IWinHTTPSession;
+ connect : IWinHTTPConnection;
+ url : IWinHTTPUrl;
+ sPath : string;
+begin
+ url := TWinHTTPUrlImpl.Create( FUri);
+
+ session := TWinHTTPSessionImpl.Create('Apache Thrift Delphi Client');
+ connect := session.Connect( url.HostName, url.Port);
+
+ sPath := url.UrlPath + url.ExtraInfo;
+ result := connect.OpenRequest( (url.Scheme = 'https'), 'POST', sPath, 'application/x-thrift');
+
+ // setting a timeout value to 0 (zero) means "no timeout" for that setting
+ result.SetTimeouts( DnsResolveTimeout, ConnectionTimeout, SendTimeout, ReadTimeout);
+
+ result.AddRequestHeader( 'Content-Type: application/x-thrift', WINHTTP_ADDREQ_FLAG_ADD);
+
+ for pair in FCustomHeaders do begin
+ Result.AddRequestHeader( pair.Key +': '+ pair.Value, WINHTTP_ADDREQ_FLAG_ADD);
+ end;
+end;
+
+function TWinHTTPClientImpl.GetDnsResolveTimeout: Integer;
+begin
+ Result := FDnsResolveTimeout;
+end;
+
+procedure TWinHTTPClientImpl.SetDnsResolveTimeout(const Value: Integer);
+begin
+ FDnsResolveTimeout := Value;
+end;
+
+function TWinHTTPClientImpl.GetConnectionTimeout: Integer;
+begin
+ Result := FConnectionTimeout;
+end;
+
+procedure TWinHTTPClientImpl.SetConnectionTimeout(const Value: Integer);
+begin
+ FConnectionTimeout := Value;
+end;
+
+function TWinHTTPClientImpl.GetSendTimeout: Integer;
+begin
+ Result := FSendTimeout;
+end;
+
+procedure TWinHTTPClientImpl.SetSendTimeout(const Value: Integer);
+begin
+ FSendTimeout := Value;
+end;
+
+function TWinHTTPClientImpl.GetReadTimeout: Integer;
+begin
+ Result := FReadTimeout;
+end;
+
+procedure TWinHTTPClientImpl.SetReadTimeout(const Value: Integer);
+begin
+ FReadTimeout := Value;
+end;
+
+function TWinHTTPClientImpl.GetCustomHeaders: IThriftDictionary<string,string>;
+begin
+ Result := FCustomHeaders;
+end;
+
+function TWinHTTPClientImpl.GetIsOpen: Boolean;
+begin
+ Result := True;
+end;
+
+procedure TWinHTTPClientImpl.Open;
+begin
+ FreeAndNil( FOutputMemoryStream);
+ FOutputMemoryStream := TMemoryStream.Create;
+end;
+
+procedure TWinHTTPClientImpl.Close;
+begin
+ FInputStream := nil;
+ FreeAndNil( FOutputMemoryStream);
+end;
+
+procedure TWinHTTPClientImpl.Flush;
+begin
+ try
+ SendRequest;
+ finally
+ FreeAndNil( FOutputMemoryStream);
+ FOutputMemoryStream := TMemoryStream.Create;
+ ASSERT( FOutputMemoryStream <> nil);
+ end;
+end;
+
+function TWinHTTPClientImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer;
+begin
+ if FInputStream = nil then begin
+ raise TTransportExceptionNotOpen.Create('No request has been sent');
+ end;
+
+ try
+ Result := FInputStream.Read( pBuf, buflen, off, len)
+ except
+ on E: Exception
+ do raise TTransportExceptionUnknown.Create(E.Message);
+ end;
+end;
+
+procedure TWinHTTPClientImpl.SendRequest;
+var
+ http : IWinHTTPRequest;
+ pData : PByte;
+ len : Integer;
+begin
+ http := CreateRequest;
+
+ pData := FOutputMemoryStream.Memory;
+ len := FOutputMemoryStream.Size;
+
+ // send all data immediately, since we have it in memory
+ if not http.SendRequest( pData, len, 0)
+ then raise TTransportExceptionUnknown.Create('send request error');
+
+ // end request and start receiving
+ if not http.FlushAndReceiveResponse
+ then raise TTransportExceptionInterrupted.Create('flush/receive error');
+
+ FInputStream := THTTPResponseStream.Create(http);
+end;
+
+procedure TWinHTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer);
+var pTmp : PByte;
+begin
+ pTmp := pBuf;
+ Inc(pTmp,off);
+ FOutputMemoryStream.Write( pTmp^, len);
+end;
+
+
+{ TWinHTTPClientImpl.THTTPResponseStream }
+
+constructor TWinHTTPClientImpl.THTTPResponseStream.Create( const aRequest : IWinHTTPRequest);
+begin
+ inherited Create;
+ FRequest := aRequest;
+end;
+
+destructor TWinHTTPClientImpl.THTTPResponseStream.Destroy;
+begin
+ try
+ Close;
+ finally
+ inherited Destroy;
+ end;
+end;
+
+procedure TWinHTTPClientImpl.THTTPResponseStream.Close;
+begin
+ FRequest := nil;
+end;
+
+procedure TWinHTTPClientImpl.THTTPResponseStream.Flush;
+begin
+ raise ENotImplemented(ClassName+'.Flush');
+end;
+
+function TWinHTTPClientImpl.THTTPResponseStream.IsOpen: Boolean;
+begin
+ Result := FRequest <> nil;
+end;
+
+procedure TWinHTTPClientImpl.THTTPResponseStream.Open;
+begin
+ // nothing to do
+end;
+
+procedure TWinHTTPClientImpl.THTTPResponseStream.Write(const pBuf : Pointer; offset, count: Integer);
+begin
+ inherited; // check pointers
+ raise ENotImplemented(ClassName+'.Write');
+end;
+
+function TWinHTTPClientImpl.THTTPResponseStream.Read(const pBuf : Pointer; const buflen : Integer; offset, count: Integer): Integer;
+var pTmp : PByte;
+begin
+ inherited; // check pointers
+
+ if count >= buflen-offset
+ then count := buflen-offset;
+
+ if count > 0 then begin
+ pTmp := pBuf;
+ Inc( pTmp, offset);
+ Result := FRequest.ReadData( pTmp, count);
+ ASSERT( Result >= 0);
+ end
+ else Result := 0;
+end;
+
+function TWinHTTPClientImpl.THTTPResponseStream.ToArray: TBytes;
+begin
+ raise ENotImplemented(ClassName+'.ToArray');
+end;
+
+
+end.
diff --git a/lib/delphi/src/Thrift.Transport.pas b/lib/delphi/src/Thrift.Transport.pas
index dad9ab7..1f8fdb0 100644
--- a/lib/delphi/src/Thrift.Transport.pas
+++ b/lib/delphi/src/Thrift.Transport.pas
@@ -29,9 +29,9 @@
Math,
Generics.Collections,
{$IFDEF OLD_UNIT_NAMES}
- ActiveX, msxml, WinSock, Sockets,
+ WinSock, Sockets,
{$ELSE}
- Winapi.ActiveX, Winapi.msxml, Winapi.WinSock,
+ Winapi.WinSock,
{$IFDEF OLD_SOCKETS}
Web.Win.Sockets,
{$ELSE}
@@ -41,6 +41,7 @@
Thrift.Collections,
Thrift.Exception,
Thrift.Utils,
+ Thrift.WinHTTP,
Thrift.Stream;
type
@@ -137,47 +138,6 @@
property CustomHeaders: IThriftDictionary<string,string> read GetCustomHeaders;
end;
- THTTPClientImpl = class( TTransportImpl, IHTTPClient)
- private
- FUri : string;
- FInputStream : IThriftStream;
- FOutputStream : IThriftStream;
- FDnsResolveTimeout : Integer;
- FConnectionTimeout : Integer;
- FSendTimeout : Integer;
- FReadTimeout : Integer;
- FCustomHeaders : IThriftDictionary<string,string>;
-
- function CreateRequest: IXMLHTTPRequest;
- protected
- function GetIsOpen: Boolean; override;
- procedure Open(); override;
- procedure Close(); override;
- function Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override;
- procedure Write( const pBuf : Pointer; off, len : Integer); override;
- procedure Flush; override;
-
- procedure SetDnsResolveTimeout(const Value: Integer);
- function GetDnsResolveTimeout: Integer;
- procedure SetConnectionTimeout(const Value: Integer);
- function GetConnectionTimeout: Integer;
- procedure SetSendTimeout(const Value: Integer);
- function GetSendTimeout: Integer;
- procedure SetReadTimeout(const Value: Integer);
- function GetReadTimeout: Integer;
-
- function GetCustomHeaders: IThriftDictionary<string,string>;
- procedure SendRequest;
- property DnsResolveTimeout: Integer read GetDnsResolveTimeout write SetDnsResolveTimeout;
- property ConnectionTimeout: Integer read GetConnectionTimeout write SetConnectionTimeout;
- property SendTimeout: Integer read GetSendTimeout write SetSendTimeout;
- property ReadTimeout: Integer read GetReadTimeout write SetReadTimeout;
- property CustomHeaders: IThriftDictionary<string,string> read GetCustomHeaders;
- public
- constructor Create( const AUri: string);
- destructor Destroy; override;
- end;
-
IServerTransport = interface
['{C43B87ED-69EA-47C4-B77C-15E288252900}']
procedure Listen;
@@ -472,170 +432,6 @@
Self.Write( pBuf, 0, len);
end;
-{ THTTPClientImpl }
-
-constructor THTTPClientImpl.Create(const AUri: string);
-begin
- inherited Create;
- FUri := AUri;
-
- // defaults according to MSDN
- FDnsResolveTimeout := 0; // no timeout
- FConnectionTimeout := 60 * 1000;
- FSendTimeout := 30 * 1000;
- FReadTimeout := 30 * 1000;
-
- FCustomHeaders := TThriftDictionaryImpl<string,string>.Create;
- FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
-end;
-
-function THTTPClientImpl.CreateRequest: IXMLHTTPRequest;
-var
- pair : TPair<string,string>;
- srvHttp : IServerXMLHTTPRequest;
-begin
- {$IF CompilerVersion >= 21.0}
- Result := CoServerXMLHTTP.Create;
- {$ELSE}
- Result := CoXMLHTTPRequest.Create;
- {$IFEND}
-
- // setting a timeout value to 0 (zero) means "no timeout" for that setting
- if Supports( result, IServerXMLHTTPRequest, srvHttp)
- then srvHttp.setTimeouts( DnsResolveTimeout, ConnectionTimeout, SendTimeout, ReadTimeout);
-
- Result.open('POST', FUri, False, '', '');
- Result.setRequestHeader( 'Content-Type', 'application/x-thrift');
- Result.setRequestHeader( 'Accept', 'application/x-thrift');
- Result.setRequestHeader( 'User-Agent', 'Delphi/IHTTPClient');
-
- for pair in FCustomHeaders do begin
- Result.setRequestHeader( pair.Key, pair.Value );
- end;
-end;
-
-destructor THTTPClientImpl.Destroy;
-begin
- Close;
- inherited;
-end;
-
-function THTTPClientImpl.GetDnsResolveTimeout: Integer;
-begin
- Result := FDnsResolveTimeout;
-end;
-
-procedure THTTPClientImpl.SetDnsResolveTimeout(const Value: Integer);
-begin
- FDnsResolveTimeout := Value;
-end;
-
-function THTTPClientImpl.GetConnectionTimeout: Integer;
-begin
- Result := FConnectionTimeout;
-end;
-
-procedure THTTPClientImpl.SetConnectionTimeout(const Value: Integer);
-begin
- FConnectionTimeout := Value;
-end;
-
-function THTTPClientImpl.GetSendTimeout: Integer;
-begin
- Result := FSendTimeout;
-end;
-
-procedure THTTPClientImpl.SetSendTimeout(const Value: Integer);
-begin
- FSendTimeout := Value;
-end;
-
-function THTTPClientImpl.GetReadTimeout: Integer;
-begin
- Result := FReadTimeout;
-end;
-
-procedure THTTPClientImpl.SetReadTimeout(const Value: Integer);
-begin
- FReadTimeout := Value;
-end;
-
-function THTTPClientImpl.GetCustomHeaders: IThriftDictionary<string,string>;
-begin
- Result := FCustomHeaders;
-end;
-
-function THTTPClientImpl.GetIsOpen: Boolean;
-begin
- Result := True;
-end;
-
-procedure THTTPClientImpl.Open;
-begin
- FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
-end;
-
-procedure THTTPClientImpl.Close;
-begin
- FInputStream := nil;
- FOutputStream := nil;
-end;
-
-procedure THTTPClientImpl.Flush;
-begin
- try
- SendRequest;
- finally
- FOutputStream := nil;
- FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
- ASSERT( FOutputStream <> nil);
- end;
-end;
-
-function THTTPClientImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer;
-begin
- if FInputStream = nil then begin
- raise TTransportExceptionNotOpen.Create('No request has been sent');
- end;
-
- try
- Result := FInputStream.Read( pBuf, buflen, off, len)
- except
- on E: Exception
- do raise TTransportExceptionUnknown.Create(E.Message);
- end;
-end;
-
-procedure THTTPClientImpl.SendRequest;
-var
- xmlhttp : IXMLHTTPRequest;
- ms : TMemoryStream;
- a : TBytes;
- len : Integer;
-begin
- xmlhttp := CreateRequest;
-
- ms := TMemoryStream.Create;
- try
- a := FOutputStream.ToArray;
- len := Length(a);
- if len > 0 then begin
- ms.WriteBuffer( Pointer(@a[0])^, len);
- end;
- ms.Position := 0;
- xmlhttp.send( IUnknown( TStreamAdapter.Create( ms, soReference )));
- FInputStream := nil;
- FInputStream := TThriftStreamAdapterCOM.Create( IUnknown( xmlhttp.responseStream) as IStream);
- finally
- ms.Free;
- end;
-end;
-
-procedure THTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer);
-begin
- FOutputStream.Write( pBuf, off, len);
-end;
-
{ TTransportException }
function TTransportException.GetType: TExceptionType;
diff --git a/lib/delphi/src/Thrift.Utils.pas b/lib/delphi/src/Thrift.Utils.pas
index 7e57863..11c4f3e 100644
--- a/lib/delphi/src/Thrift.Utils.pas
+++ b/lib/delphi/src/Thrift.Utils.pas
@@ -25,12 +25,19 @@
uses
{$IFDEF OLD_UNIT_NAMES}
- Classes, Windows, SysUtils, Character, SyncObjs;
+ Classes, Windows, SysUtils, Character, SyncObjs, TypInfo, Rtti;
{$ELSE}
- System.Classes, Winapi.Windows, System.SysUtils, System.Character, System.SyncObjs;
+ System.Classes, Winapi.Windows, System.SysUtils, System.Character,
+ System.SyncObjs, System.TypInfo, System.Rtti;
{$ENDIF}
type
+ ISupportsToString = interface
+ ['{AF71C350-E0CD-4E94-B77C-0310DC8227FF}']
+ function ToString : string;
+ end;
+
+
IOverlappedHelper = interface
['{A1832EFA-2E02-4884-8F09-F0A0277157FA}']
function Overlapped : TOverlapped;
@@ -55,6 +62,13 @@
end;
+ TThriftStringBuilder = class( TStringBuilder)
+ public
+ function Append(const Value: TBytes): TStringBuilder; overload;
+ function Append(const Value: ISupportsToString): TStringBuilder; overload;
+ end;
+
+
Base64Utils = class sealed
public
class function Encode( const src : TBytes; srcOff, len : Integer; dst : TBytes; dstOff : Integer) : Integer; static;
@@ -68,6 +82,16 @@
class function IsLowSurrogate( const c : Char) : Boolean; static; inline;
end;
+ EnumUtils<T> = class sealed
+ public
+ class function ToString(const value : Integer) : string; reintroduce; static; inline;
+ end;
+
+ StringUtils<T> = class sealed
+ public
+ class function ToString(const value : T) : string; reintroduce; static; inline;
+ end;
+
{$IFDEF Win64}
function InterlockedExchangeAdd64( var Addend : Int64; Value : Int64) : Int64;
@@ -256,4 +280,54 @@
{$ENDIF}
+{ EnumUtils<T> }
+
+class function EnumUtils<T>.ToString(const value : Integer) : string;
+var pType : PTypeInfo;
+begin
+ pType := PTypeInfo(TypeInfo(T));
+ if Assigned(pType) and (pType^.Kind = tkEnumeration)
+ then result := GetEnumName(pType,value)
+ else result := IntToStr(Ord(value));
+end;
+
+
+{ StringUtils<T> }
+
+class function StringUtils<T>.ToString(const value : T) : string;
+type PInterface = ^IInterface;
+var pType : PTypeInfo;
+ stos : ISupportsToString;
+ pIntf : PInterface; // Workaround: Rio does not allow the direct typecast
+begin
+ pType := PTypeInfo(TypeInfo(T));
+ if Assigned(pType) then begin
+ case pType^.Kind of
+ tkInterface : begin
+ pIntf := PInterface(@value);
+ if Supports( pIntf^, ISupportsToString, stos) then begin
+ result := stos.toString;
+ Exit;
+ end;
+ end;
+ end;
+ end;
+
+ result := TValue.From<T>(value).ToString;
+end;
+
+
+{ TThriftStringBuilder }
+
+function TThriftStringBuilder.Append(const Value: TBytes): TStringBuilder;
+begin
+ Result := Append( string( RawByteString(Value)) );
+end;
+
+function TThriftStringBuilder.Append( const Value: ISupportsToString): TStringBuilder;
+begin
+ Result := Append( Value.ToString );
+end;
+
+
end.
diff --git a/lib/delphi/src/Thrift.WinHTTP.pas b/lib/delphi/src/Thrift.WinHTTP.pas
new file mode 100644
index 0000000..6ad8400
--- /dev/null
+++ b/lib/delphi/src/Thrift.WinHTTP.pas
@@ -0,0 +1,808 @@
+(*
+ * 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 Thrift.WinHTTP;
+
+{$I Thrift.Defines.inc}
+{$SCOPEDENUMS ON}
+
+// packing according to winhttp.h
+{$IFDEF Win64} {$ALIGN 8} {$ELSE} {$ALIGN 4} {$ENDIF}
+
+interface
+
+uses
+ Windows,
+ Classes,
+ SysUtils,
+ Math,
+ Generics.Collections;
+
+
+type
+ HINTERNET = type Pointer;
+ INTERNET_PORT = type WORD;
+ INTERNET_SCHEME = type Integer;
+ LPLPCWSTR = ^LPCWSTR;
+
+ LPURL_COMPONENTS = ^URL_COMPONENTS;
+ URL_COMPONENTS = record
+ dwStructSize : DWORD; // set to SizeOf(URL_COMPONENTS)
+ lpszScheme : LPWSTR; // scheme name
+ dwSchemeLength : DWORD;
+ nScheme : INTERNET_SCHEME; // enumerated scheme type
+ lpszHostName : LPWSTR; // host name
+ dwHostNameLength : DWORD;
+ nPort : INTERNET_PORT; // port number
+ lpszUserName : LPWSTR; // user name
+ dwUserNameLength : DWORD;
+ lpszPassword : LPWSTR; // password
+ dwPasswordLength : DWORD;
+ lpszUrlPath : LPWSTR; // URL-path
+ dwUrlPathLength : DWORD;
+ lpszExtraInfo : LPWSTR; // extra information
+ dwExtraInfoLength : DWORD;
+ end;
+
+ URL_COMPONENTSW = URL_COMPONENTS;
+ LPURL_COMPONENTSW = LPURL_COMPONENTS;
+
+
+function WinHttpCloseHandle( aHandle : HINTERNET) : BOOL; stdcall;
+
+function WinHttpOpen( const pszAgentW : LPCWSTR;
+ const dwAccessType : DWORD;
+ const pszProxyW : LPCWSTR;
+ const pszProxyBypassW : LPCWSTR;
+ const dwFlags : DWORD
+ ) : HINTERNET; stdcall;
+
+function WinHttpConnect( const hSession : HINTERNET;
+ const pswzServerName : LPCWSTR;
+ const nServerPort : INTERNET_PORT;
+ const dwReserved : DWORD
+ ) : HINTERNET; stdcall;
+
+function WinHttpOpenRequest( const hConnect : HINTERNET;
+ const pwszVerb, pwszObjectName, pwszVersion, pwszReferrer : LPCWSTR;
+ const ppwszAcceptTypes : LPLPCWSTR;
+ const dwFlags : DWORD
+ ) : HINTERNET; stdcall;
+
+function WinHttpSetTimeouts( const hRequestOrSession : HINTERNET;
+ const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32
+ ) : BOOL; stdcall;
+
+function WinHttpAddRequestHeaders( const hRequest : HINTERNET;
+ const pwszHeaders : LPCWSTR;
+ const dwHeadersLengthInChars : DWORD;
+ const dwModifiers : DWORD
+ ) : BOOL; stdcall;
+
+function WinHttpSendRequest( const hRequest : HINTERNET;
+ const lpszHeaders : LPCWSTR;
+ const dwHeadersLength : DWORD;
+ const lpOptional : Pointer;
+ const dwOptionalLength : DWORD;
+ const dwTotalLength : DWORD;
+ const pContext : Pointer
+ ) : BOOL; stdcall;
+
+function WinHttpWriteData( const hRequest : HINTERNET;
+ const pBuf : Pointer;
+ const dwBytesToWrite : DWORD;
+ out dwBytesWritten : DWORD
+ ) : BOOL; stdcall;
+
+function WinHttpReceiveResponse( const hRequest : HINTERNET; const lpReserved : Pointer) : BOOL; stdcall;
+
+function WinHttpQueryHeaders( const hRequest : HINTERNET;
+ const dwInfoLevel : DWORD;
+ const pwszName : LPCWSTR;
+ const lpBuffer : Pointer;
+ var dwBufferLength : DWORD;
+ var dwIndex : DWORD
+ ) : BOOL; stdcall;
+
+function WinHttpQueryDataAvailable( const hRequest : HINTERNET;
+ var dwNumberOfBytesAvailable : DWORD
+ ) : BOOL; stdcall;
+
+function WinHttpReadData( const hRequest : HINTERNET;
+ const lpBuffer : Pointer;
+ const dwBytesToRead : DWORD;
+ out dwBytesRead : DWORD
+ ) : BOOL; stdcall;
+
+function WinHttpCrackUrl( const pwszUrl : LPCWSTR;
+ const dwUrlLength : DWORD;
+ const dwFlags : DWORD;
+ var urlComponents : URL_COMPONENTS
+ ) : BOOL; stdcall;
+
+function WinHttpCreateUrl( const UrlComponents : URL_COMPONENTS;
+ const dwFlags : DWORD;
+ const pwszUrl : LPCWSTR;
+ var pdwUrlLength : DWORD
+ ) : BOOL; stdcall;
+
+
+const
+ // WinHttpOpen dwAccessType values
+ WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0;
+ WINHTTP_ACCESS_TYPE_NO_PROXY = 1;
+ WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3;
+
+ // flags for WinHttpOpen():
+ WINHTTP_FLAG_ASYNC = $10000000; // want async session, requires WinHttpSetStatusCallback() usage
+
+ // ports
+ INTERNET_DEFAULT_PORT = 0; // use the protocol-specific default (80 or 443)
+
+ // flags for WinHttpOpenRequest():
+ WINHTTP_FLAG_SECURE = $00800000; // use SSL if applicable (HTTPS)
+ WINHTTP_FLAG_ESCAPE_PERCENT = $00000004; // if escaping enabled, escape percent as well
+ WINHTTP_FLAG_NULL_CODEPAGE = $00000008; // assume all symbols are ASCII, use fast convertion
+ WINHTTP_FLAG_BYPASS_PROXY_CACHE = $00000100; // add "pragma: no-cache" request header
+ WINHTTP_FLAG_REFRESH = WINHTTP_FLAG_BYPASS_PROXY_CACHE;
+ WINHTTP_FLAG_ESCAPE_DISABLE = $00000040; // disable escaping
+ WINHTTP_FLAG_ESCAPE_DISABLE_QUERY = $00000080; // if escaping enabled escape path part, but do not escape query
+
+ // flags for WinHttpSendRequest():
+ WINHTTP_NO_ADDITIONAL_HEADERS = nil;
+ WINHTTP_NO_REQUEST_DATA = nil;
+
+ // WinHttpAddRequestHeaders() dwModifiers
+ WINHTTP_ADDREQ_INDEX_MASK = $0000FFFF;
+ WINHTTP_ADDREQ_FLAGS_MASK = $FFFF0000;
+
+ WINHTTP_ADDREQ_FLAG_ADD_IF_NEW = $10000000;
+ WINHTTP_ADDREQ_FLAG_ADD = $20000000;
+ WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA = $40000000;
+ WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON = $01000000;
+ WINHTTP_ADDREQ_FLAG_COALESCE = WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA;
+ WINHTTP_ADDREQ_FLAG_REPLACE = $80000000;
+
+ // URL functions
+ ICU_NO_ENCODE = $20000000; // Don't convert unsafe characters to escape sequence
+ ICU_DECODE = $10000000; // Convert %XX escape sequences to characters
+ ICU_NO_META = $08000000; // Don't convert .. etc. meta path sequences
+ ICU_ENCODE_SPACES_ONLY = $04000000; // Encode spaces only
+ ICU_BROWSER_MODE = $02000000; // Special encode/decode rules for browser
+ ICU_ENCODE_PERCENT = $00001000; // Encode any percent (ASCII25)
+
+ ICU_ESCAPE = $80000000; // (un)escape URL characters
+ ICU_ESCAPE_AUTHORITY = $00002000; // causes InternetCreateUrlA to escape chars in authority components (user, pwd, host)
+ ICU_REJECT_USERPWD = $00004000; // rejects usrls whick have username/pwd sections
+
+ INTERNET_SCHEME_HTTP = INTERNET_SCHEME(1);
+ INTERNET_SCHEME_HTTPS = INTERNET_SCHEME(2);
+
+const
+ WINHTTP_ERROR_BASE = 12000;
+ ERROR_WINHTTP_OUT_OF_HANDLES = WINHTTP_ERROR_BASE + 1;
+ ERROR_WINHTTP_TIMEOUT = WINHTTP_ERROR_BASE + 2;
+ ERROR_WINHTTP_INTERNAL_ERROR = WINHTTP_ERROR_BASE + 4;
+ ERROR_WINHTTP_INVALID_URL = WINHTTP_ERROR_BASE + 5;
+ ERROR_WINHTTP_UNRECOGNIZED_SCHEME = WINHTTP_ERROR_BASE + 6;
+ ERROR_WINHTTP_NAME_NOT_RESOLVED = WINHTTP_ERROR_BASE + 7;
+ ERROR_WINHTTP_INVALID_OPTION = WINHTTP_ERROR_BASE + 9;
+ ERROR_WINHTTP_OPTION_NOT_SETTABLE = WINHTTP_ERROR_BASE + 11;
+ ERROR_WINHTTP_SHUTDOWN = WINHTTP_ERROR_BASE + 12;
+ ERROR_WINHTTP_LOGIN_FAILURE = WINHTTP_ERROR_BASE + 15;
+ ERROR_WINHTTP_OPERATION_CANCELLED = WINHTTP_ERROR_BASE + 17;
+ ERROR_WINHTTP_INCORRECT_HANDLE_TYPE = WINHTTP_ERROR_BASE + 18;
+ ERROR_WINHTTP_INCORRECT_HANDLE_STATE = WINHTTP_ERROR_BASE + 19;
+ ERROR_WINHTTP_CANNOT_CONNECT = WINHTTP_ERROR_BASE + 29;
+ ERROR_WINHTTP_CONNECTION_ERROR = WINHTTP_ERROR_BASE + 30;
+ ERROR_WINHTTP_RESEND_REQUEST = WINHTTP_ERROR_BASE + 32;
+ ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED = WINHTTP_ERROR_BASE + 44;
+ ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN = WINHTTP_ERROR_BASE + 100;
+ ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND = WINHTTP_ERROR_BASE + 101;
+ ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND = WINHTTP_ERROR_BASE + 102;
+ ERROR_WINHTTP_CANNOT_CALL_AFTER_OPEN = WINHTTP_ERROR_BASE + 103;
+ ERROR_WINHTTP_HEADER_NOT_FOUND = WINHTTP_ERROR_BASE + 150;
+ ERROR_WINHTTP_INVALID_SERVER_RESPONSE = WINHTTP_ERROR_BASE + 152;
+ ERROR_WINHTTP_INVALID_HEADER = WINHTTP_ERROR_BASE + 153;
+ ERROR_WINHTTP_INVALID_QUERY_REQUEST = WINHTTP_ERROR_BASE + 154;
+ ERROR_WINHTTP_HEADER_ALREADY_EXISTS = WINHTTP_ERROR_BASE + 155;
+ ERROR_WINHTTP_REDIRECT_FAILED = WINHTTP_ERROR_BASE + 156;
+ ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR = WINHTTP_ERROR_BASE + 178;
+ ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT = WINHTTP_ERROR_BASE + 166;
+ ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT = WINHTTP_ERROR_BASE + 167;
+ ERROR_WINHTTP_NOT_INITIALIZED = WINHTTP_ERROR_BASE + 172;
+ ERROR_WINHTTP_SECURE_FAILURE = WINHTTP_ERROR_BASE + 175;
+
+ // Certificate security errors. Additional information is provided
+ // via the WINHTTP_CALLBACK_STATUS_SECURE_FAILURE callback notification.
+ ERROR_WINHTTP_SECURE_CERT_DATE_INVALID = WINHTTP_ERROR_BASE + 37;
+ ERROR_WINHTTP_SECURE_CERT_CN_INVALID = WINHTTP_ERROR_BASE + 38;
+ ERROR_WINHTTP_SECURE_INVALID_CA = WINHTTP_ERROR_BASE + 45;
+ ERROR_WINHTTP_SECURE_CERT_REV_FAILED = WINHTTP_ERROR_BASE + 57;
+ ERROR_WINHTTP_SECURE_CHANNEL_ERROR = WINHTTP_ERROR_BASE + 157;
+ ERROR_WINHTTP_SECURE_INVALID_CERT = WINHTTP_ERROR_BASE + 169;
+ ERROR_WINHTTP_SECURE_CERT_REVOKED = WINHTTP_ERROR_BASE + 170;
+ ERROR_WINHTTP_SECURE_CERT_WRONG_USAGE = WINHTTP_ERROR_BASE + 179;
+
+ ERROR_WINHTTP_AUTODETECTION_FAILED = WINHTTP_ERROR_BASE + 180;
+ ERROR_WINHTTP_HEADER_COUNT_EXCEEDED = WINHTTP_ERROR_BASE + 181;
+ ERROR_WINHTTP_HEADER_SIZE_OVERFLOW = WINHTTP_ERROR_BASE + 182;
+ ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW = WINHTTP_ERROR_BASE + 183;
+ ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW = WINHTTP_ERROR_BASE + 184;
+ ERROR_WINHTTP_CLIENT_CERT_NO_PRIVATE_KEY = WINHTTP_ERROR_BASE + 185;
+ ERROR_WINHTTP_CLIENT_CERT_NO_ACCESS_PRIVATE_KEY = WINHTTP_ERROR_BASE + 186;
+
+
+const
+ WINHTTP_THRIFT_DEFAULTS = WINHTTP_FLAG_NULL_CODEPAGE
+ or WINHTTP_FLAG_BYPASS_PROXY_CACHE
+ or WINHTTP_FLAG_ESCAPE_DISABLE;
+
+
+type
+ IWinHTTPRequest = interface
+ ['{35C6D9D4-FDCE-42C6-B84C-9294E6FB904C}']
+ function Handle : HINTERNET;
+ function AddRequestHeader( const aHeader : string; const addflag : DWORD = WINHTTP_ADDREQ_FLAG_ADD) : Boolean;
+ function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
+ function SendRequest( const pBuf : Pointer; const dwBytes : DWORD; const dwExtra : DWORD = 0) : Boolean;
+ function WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD;
+ function FlushAndReceiveResponse : Boolean;
+ function ReadData( const dwRead : DWORD) : TBytes; overload;
+ function ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD; overload;
+ end;
+
+ IWinHTTPConnection = interface
+ ['{1C4F78B5-1525-4788-B638-A0E41BCF4D43}']
+ function Handle : HINTERNET;
+ function OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest;
+ end;
+
+ IWinHTTPSession = interface
+ ['{B6F8BD98-0605-4A9E-B671-4CB191D74A5E}']
+ function Handle : HINTERNET;
+ function Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT = INTERNET_DEFAULT_PORT) : IWinHTTPConnection;
+ function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
+ end;
+
+ IWinHTTPUrl = interface
+ ['{78BE977C-4171-4AF5-A250-FD2890205E63}']
+ // url parts getter
+ function GetScheme : UnicodeString;
+ function GetNumScheme : INTERNET_SCHEME;
+ function GetHostName : UnicodeString;
+ function GetPort : INTERNET_PORT;
+ function GetUserName : UnicodeString;
+ function GetPassword : UnicodeString;
+ function GetUrlPath : UnicodeString;
+ function GetExtraInfo : UnicodeString;
+
+ // url parts setter
+ procedure SetScheme( const value : UnicodeString);
+ procedure SetHostName ( const value : UnicodeString);
+ procedure SetPort( const value : INTERNET_PORT);
+ procedure SetUserName( const value : UnicodeString);
+ procedure SetPassword( const value : UnicodeString);
+ procedure SetUrlPath( const value : UnicodeString);
+ procedure SetExtraInfo( const value : UnicodeString);
+
+ // url as a whole
+ function BuildUrl : UnicodeString;
+ procedure CrackUrl( const value : UnicodeString);
+
+ // url parts
+ property Scheme : UnicodeString read GetScheme write SetScheme;
+ property NumScheme : INTERNET_SCHEME read GetNumScheme; // readonly
+ property HostName : UnicodeString read GetHostName write SetHostName;
+ property Port : INTERNET_PORT read GetPort write SetPort;
+ property UserName : UnicodeString read GetUserName write SetUserName;
+ property Password : UnicodeString read GetPassword write SetPassword;
+ property UrlPath : UnicodeString read GetUrlPath write SetUrlPath;
+ property ExtraInfo : UnicodeString read GetExtraInfo write SetExtraInfo;
+
+ // url as a whole
+ property CompleteURL : UnicodeString read BuildUrl write CrackUrl;
+ end;
+
+
+
+
+type
+ TWinHTTPHandleObjectImpl = class( TInterfacedObject)
+ strict protected
+ FHandle : HINTERNET;
+ function Handle : HINTERNET;
+ public
+ constructor Create( const aHandle : HINTERNET);
+ destructor Destroy; override;
+ end;
+
+
+ TWinHTTPSessionImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPSession)
+ strict protected
+
+ // IWinHTTPSession
+ function Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT = INTERNET_DEFAULT_PORT) : IWinHTTPConnection;
+ function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
+
+ public
+ constructor Create( const aAgent : UnicodeString;
+ const aAccessType : DWORD = WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
+ const aProxy : UnicodeString = '';
+ const aProxyBypass : UnicodeString = '';
+ const aFlags : DWORD = 0);
+ destructor Destroy; override;
+ end;
+
+
+ TWinHTTPConnectionImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPConnection)
+ strict protected
+ FSession : IWinHTTPSession;
+
+ // IWinHTTPConnection
+ function OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest;
+
+ public
+ constructor Create( const aSession : IWinHTTPSession; const aHostName : UnicodeString; const aPort : INTERNET_PORT);
+ destructor Destroy; override;
+ end;
+
+
+ TAcceptTypesArray = array of string;
+
+ TWinHTTPRequestImpl = class( TWinHTTPHandleObjectImpl, IWinHTTPRequest)
+ strict protected
+ FConnection : IWinHTTPConnection;
+
+ // IWinHTTPRequest
+ function AddRequestHeader( const aHeader : string; const addflag : DWORD = WINHTTP_ADDREQ_FLAG_ADD) : Boolean;
+ function SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
+ function SendRequest( const pBuf : Pointer; const dwBytes : DWORD; const dwExtra : DWORD = 0) : Boolean;
+ function WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD;
+ function FlushAndReceiveResponse : Boolean;
+ function ReadData( const dwRead : DWORD) : TBytes; overload;
+ function ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD; overload;
+
+ public
+ constructor Create( const aConnection : IWinHTTPConnection;
+ const aVerb, aObjName : UnicodeString;
+ const aVersion : UnicodeString = '';
+ const aReferrer : UnicodeString = '';
+ const aAcceptTypes : UnicodeString = '*/*';
+ const aFlags : DWORD = WINHTTP_THRIFT_DEFAULTS
+ );
+
+ destructor Destroy; override;
+ end;
+
+
+ TWinHTTPUrlImpl = class( TInterfacedObject, IWinHTTPUrl)
+ strict private
+ FScheme : UnicodeString;
+ FNumScheme : INTERNET_SCHEME;
+ FHostName : UnicodeString;
+ FPort : INTERNET_PORT;
+ FUserName : UnicodeString;
+ FPassword : UnicodeString;
+ FUrlPath : UnicodeString;
+ FExtraInfo : UnicodeString;
+
+ strict protected
+ // url parts getter
+ function GetScheme : UnicodeString;
+ function GetNumScheme : INTERNET_SCHEME;
+ function GetHostName : UnicodeString;
+ function GetPort : INTERNET_PORT;
+ function GetUserName : UnicodeString;
+ function GetPassword : UnicodeString;
+ function GetUrlPath : UnicodeString;
+ function GetExtraInfo : UnicodeString;
+
+ // url parts setter
+ procedure SetScheme( const value : UnicodeString);
+ procedure SetHostName ( const value : UnicodeString);
+ procedure SetPort( const value : INTERNET_PORT);
+ procedure SetUserName( const value : UnicodeString);
+ procedure SetPassword( const value : UnicodeString);
+ procedure SetUrlPath( const value : UnicodeString);
+ procedure SetExtraInfo( const value : UnicodeString);
+
+ // url as a whole
+ function BuildUrl : UnicodeString;
+ procedure CrackUrl( const value : UnicodeString);
+
+ public
+ constructor Create( const aUri : UnicodeString);
+ destructor Destroy; override;
+ end;
+
+
+ EWinHTTPException = class(Exception);
+
+implementation
+
+const WINHTTP_DLL = 'WinHTTP.dll';
+
+function WinHttpCloseHandle; stdcall; external WINHTTP_DLL;
+function WinHttpOpen; stdcall; external WINHTTP_DLL;
+function WinHttpConnect; stdcall; external WINHTTP_DLL;
+function WinHttpOpenRequest; stdcall; external WINHTTP_DLL;
+function WinHttpSendRequest; stdcall; external WINHTTP_DLL;
+function WinHttpSetTimeouts; stdcall; external WINHTTP_DLL;
+function WinHttpAddRequestHeaders; stdcall; external WINHTTP_DLL;
+function WinHttpWriteData; stdcall; external WINHTTP_DLL;
+function WinHttpReceiveResponse; stdcall; external WINHTTP_DLL;
+function WinHttpQueryHeaders; stdcall; external WINHTTP_DLL;
+function WinHttpQueryDataAvailable; stdcall; external WINHTTP_DLL;
+function WinHttpReadData; stdcall; external WINHTTP_DLL;
+function WinHttpCrackUrl; stdcall; external WINHTTP_DLL;
+function WinHttpCreateUrl; stdcall; external WINHTTP_DLL;
+
+
+{ TWinHTTPHandleObjectImpl }
+
+constructor TWinHTTPHandleObjectImpl.Create( const aHandle : HINTERNET);
+begin
+ inherited Create;
+ FHandle := aHandle;
+
+ if FHandle = nil
+ then raise EWinHTTPException.Create('Invalid handle');
+end;
+
+
+destructor TWinHTTPHandleObjectImpl.Destroy;
+begin
+ try
+ if Assigned(FHandle) then begin
+ WinHttpCloseHandle(FHandle);
+ FHandle := nil;
+ end;
+
+ finally
+ inherited Destroy;
+ end;
+end;
+
+
+function TWinHTTPHandleObjectImpl.Handle : HINTERNET;
+begin
+ result := FHandle;
+end;
+
+
+{ TWinHTTPSessionImpl }
+
+
+constructor TWinHTTPSessionImpl.Create( const aAgent : UnicodeString; const aAccessType : DWORD;
+ const aProxy, aProxyBypass : UnicodeString; const aFlags : DWORD);
+var handle : HINTERNET;
+begin
+ handle := WinHttpOpen( PWideChar(aAgent), aAccessType,
+ PWideChar(Pointer(aProxy)), // may be nil
+ PWideChar(Pointer(aProxyBypass)), // may be nil
+ aFlags);
+ if handle = nil then RaiseLastOSError;
+ inherited Create( handle);
+end;
+
+
+destructor TWinHTTPSessionImpl.Destroy;
+begin
+ inherited Destroy;
+ // add code here
+end;
+
+
+function TWinHTTPSessionImpl.Connect( const aHostName : UnicodeString; const aPort : INTERNET_PORT) : IWinHTTPConnection;
+begin
+ result := TWinHTTPConnectionImpl.Create( Self, aHostName, aPort);
+end;
+
+
+function TWinHTTPSessionImpl.SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
+begin
+ result := WinHttpSetTimeouts( FHandle, aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout);
+end;
+
+
+{ TWinHTTPConnectionImpl }
+
+constructor TWinHTTPConnectionImpl.Create( const aSession : IWinHTTPSession; const aHostName : UnicodeString; const aPort : INTERNET_PORT);
+var handle : HINTERNET;
+begin
+ FSession := aSession;
+ handle := WinHttpConnect( FSession.Handle, PWideChar(aHostName), aPort, 0);
+ if handle = nil then RaiseLastOSError;
+ inherited Create( handle);
+end;
+
+
+destructor TWinHTTPConnectionImpl.Destroy;
+begin
+ inherited Destroy;
+ FSession := nil;
+end;
+
+
+function TWinHTTPConnectionImpl.OpenRequest( const secure : Boolean; const aVerb, aObjName, aAcceptTypes : UnicodeString) : IWinHTTPRequest;
+var dwFlags : DWORD;
+begin
+ dwFlags := WINHTTP_THRIFT_DEFAULTS;
+ if secure
+ then dwFlags := dwFlags or WINHTTP_FLAG_SECURE
+ else dwFlags := dwFlags and not WINHTTP_FLAG_SECURE;
+
+ result := TWinHTTPRequestImpl.Create( Self, aVerb, aObjName, '', '', aAcceptTypes, dwFlags);
+end;
+
+
+{ TWinHTTPRequestImpl }
+
+constructor TWinHTTPRequestImpl.Create( const aConnection : IWinHTTPConnection;
+ const aVerb, aObjName, aVersion, aReferrer : UnicodeString;
+ const aAcceptTypes : UnicodeString;
+ const aFlags : DWORD
+ );
+var handle : HINTERNET;
+ accept : array[0..1] of PWideChar;
+begin
+ FConnection := aConnection;
+
+ accept[0] := PWideChar(aAcceptTypes);
+ accept[1] := nil;
+
+ handle := WinHttpOpenRequest( FConnection.Handle,
+ PWideChar(UpperCase(aVerb)),
+ PWideChar(aObjName),
+ PWideChar(aVersion),
+ PWideChar(aReferrer),
+ @accept,
+ aFlags);
+ if handle = nil then RaiseLastOSError;
+ inherited Create( handle);
+end;
+
+
+destructor TWinHTTPRequestImpl.Destroy;
+begin
+ inherited Destroy;
+ FConnection := nil;
+end;
+
+
+function TWinHTTPRequestImpl.SetTimeouts( const aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout : Int32) : Boolean;
+begin
+ result := WinHttpSetTimeouts( FHandle, aResolveTimeout, aConnectTimeout, aSendTimeout, aReceiveTimeout);
+end;
+
+
+function TWinHTTPRequestImpl.AddRequestHeader( const aHeader : string; const addflag : DWORD) : Boolean;
+begin
+ result := WinHttpAddRequestHeaders( FHandle, PWideChar(aHeader), DWORD(-1), addflag);
+end;
+
+
+function TWinHTTPRequestImpl.SendRequest( const pBuf : Pointer; const dwBytes, dwExtra : DWORD) : Boolean;
+begin
+ result := WinHttpSendRequest( FHandle,
+ WINHTTP_NO_ADDITIONAL_HEADERS, 0,
+ pBuf, dwBytes, // number of bytes in pBuf
+ dwBytes + dwExtra, // becomes the Content-Length
+ nil); // context for async operations
+end;
+
+
+function TWinHTTPRequestImpl.WriteExtraData( const pBuf : Pointer; const dwBytes : DWORD) : DWORD;
+begin
+ if not WinHttpWriteData( FHandle, pBuf, dwBytes, result)
+ then result := 0;
+end;
+
+
+function TWinHTTPRequestImpl.FlushAndReceiveResponse : Boolean;
+begin
+ result := WinHttpReceiveResponse( FHandle, nil);
+end;
+
+
+function TWinHTTPRequestImpl.ReadData( const dwRead : DWORD) : TBytes;
+var dwAvailable, dwReceived : DWORD;
+begin
+ if WinHttpQueryDataAvailable( FHandle, dwAvailable)
+ then dwAvailable := Min( dwRead, dwAvailable)
+ else dwAvailable := 0;
+
+ SetLength( result, dwAvailable);
+ if dwAvailable = 0 then Exit;
+
+ if WinHttpReadData( FHandle, @result[0], Length(result), dwReceived)
+ then SetLength( result, dwReceived)
+ else SetLength( result, 0);
+end;
+
+
+function TWinHTTPRequestImpl.ReadData( const pBuf : Pointer; const dwRead : DWORD) : DWORD;
+var dwAvailable : DWORD;
+begin
+ if WinHttpQueryDataAvailable( FHandle, dwAvailable)
+ then dwAvailable := Min( dwRead, dwAvailable)
+ else dwAvailable := 0;
+
+ if (dwAvailable = 0)
+ or not WinHttpReadData( FHandle, pBuf, dwAvailable, result)
+ then result := 0;
+end;
+
+
+{ TWinHTTPUrlImpl }
+
+constructor TWinHTTPUrlImpl.Create(const aUri: UnicodeString);
+begin
+ inherited Create;
+ CrackUrl( aUri)
+end;
+
+
+destructor TWinHTTPUrlImpl.Destroy;
+begin
+ inherited Destroy;
+end;
+
+
+procedure TWinHTTPUrlImpl.CrackURL( const value : UnicodeString);
+const FLAGS = 0; // no special operations, leave components as-is
+var components : URL_COMPONENTS;
+begin
+ FillChar(components, SizeOf(components), 0);
+ components.dwStructSize := SizeOf(components);
+
+ if value <> '' then begin
+ { For the WinHttpCrackUrl function, [...] if the pointer member is NULL but the
+ length member is not zero, both the pointer and length members are returned. }
+ components.dwSchemeLength := DWORD(-1);
+ components.dwHostNameLength := DWORD(-1);
+ components.dwUserNameLength := DWORD(-1);
+ components.dwPasswordLength := DWORD(-1);
+ components.dwUrlPathLength := DWORD(-1);
+ components.dwExtraInfoLength := DWORD(-1);
+
+ WinHttpCrackUrl( PWideChar(value), Length(value), FLAGS, components);
+ end;
+
+ FNumScheme := components.nScheme;
+ FPort := components.nPort;
+ SetString( FScheme, components.lpszScheme, components.dwSchemeLength);
+ SetString( FHostName, components.lpszHostName, components.dwHostNameLength);
+ SetString( FUserName, components.lpszUserName, components.dwUserNameLength);
+ SetString( FPassword, components.lpszPassword, components.dwPasswordLength);
+ SetString( FUrlPath, components.lpszUrlPath, components.dwUrlPathLength);
+ SetString( FExtraInfo, components.lpszExtraInfo, components.dwExtraInfoLength);
+end;
+
+
+function TWinHTTPUrlImpl.BuildUrl : UnicodeString;
+const FLAGS = 0; // no special operations, leave components as-is
+var components : URL_COMPONENTS;
+ dwChars : DWORD;
+begin
+ FillChar(components, SizeOf(components), 0);
+ components.dwStructSize := SizeOf(components);
+ components.lpszScheme := PWideChar(FScheme);
+ components.dwSchemeLength := Length(FScheme);
+ components.lpszHostName := PWideChar(FHostName);
+ components.dwHostNameLength := Length(FHostName);
+ components.nPort := FPort;
+ components.lpszUserName := PWideChar(FUserName);
+ components.dwUserNameLength := Length(FUserName);
+ components.lpszPassword := PWideChar(FPassword);
+ components.dwPasswordLength := Length(FPassword);
+ components.lpszUrlPath := PWideChar(FUrlPath);
+ components.dwUrlPathLength := Length(FUrlPath);
+ components.lpszExtraInfo := PWideChar(FExtraInfo);
+ components.dwExtraInfoLength := Length(FExtraInfo);
+
+ WinHttpCreateUrl( components, FLAGS, nil, dwChars);
+ if dwChars = 0
+ then result := ''
+ else begin
+ SetLength( result, dwChars + 1);
+ WinHttpCreateUrl( components, FLAGS, @result[1], dwChars);
+ SetLength( result, dwChars); // cut off terminating #0
+ end;
+end;
+
+
+function TWinHTTPUrlImpl.GetExtraInfo: UnicodeString;
+begin
+ result := FExtraInfo;
+end;
+
+function TWinHTTPUrlImpl.GetHostName: UnicodeString;
+begin
+ result := FHostName;
+end;
+
+function TWinHTTPUrlImpl.GetNumScheme: INTERNET_SCHEME;
+begin
+ result := FNumScheme;
+end;
+
+function TWinHTTPUrlImpl.GetPassword: UnicodeString;
+begin
+ result := FPassword;
+end;
+
+function TWinHTTPUrlImpl.GetPort: INTERNET_PORT;
+begin
+ result := FPort;
+end;
+
+function TWinHTTPUrlImpl.GetScheme: UnicodeString;
+begin
+ result := FScheme;
+end;
+
+function TWinHTTPUrlImpl.GetUrlPath: UnicodeString;
+begin
+ result := FUrlPath;
+end;
+
+function TWinHTTPUrlImpl.GetUserName: UnicodeString;
+begin
+ result := FUserName;
+end;
+
+procedure TWinHTTPUrlImpl.SetExtraInfo(const value: UnicodeString);
+begin
+ FExtraInfo := value;
+end;
+
+procedure TWinHTTPUrlImpl.SetHostName(const value: UnicodeString);
+begin
+ FHostName := value;
+end;
+
+procedure TWinHTTPUrlImpl.SetPassword(const value: UnicodeString);
+begin
+ FPassword := value;
+end;
+
+procedure TWinHTTPUrlImpl.SetPort(const value: INTERNET_PORT);
+begin
+ FPort := value;
+end;
+
+procedure TWinHTTPUrlImpl.SetScheme(const value: UnicodeString);
+begin
+ FScheme := value;
+end;
+
+procedure TWinHTTPUrlImpl.SetUrlPath(const value: UnicodeString);
+begin
+ FUrlPath := value;
+end;
+
+procedure TWinHTTPUrlImpl.SetUserName(const value: UnicodeString);
+begin
+ FUserName := value;
+end;
+
+
+end.
+
diff --git a/lib/delphi/src/Thrift.pas b/lib/delphi/src/Thrift.pas
index dada330..2ee8344 100644
--- a/lib/delphi/src/Thrift.pas
+++ b/lib/delphi/src/Thrift.pas
@@ -27,7 +27,7 @@
Thrift.Protocol;
const
- Version = '0.12.1';
+ Version = '0.13.0';
type
TException = Thrift.Exception.TException; // compatibility alias
diff --git a/lib/delphi/test/TestClient.pas b/lib/delphi/test/TestClient.pas
index 0fa43b0..55bf92b 100644
--- a/lib/delphi/test/TestClient.pas
+++ b/lib/delphi/test/TestClient.pas
@@ -43,6 +43,8 @@
Thrift.Protocol.JSON,
Thrift.Protocol,
Thrift.Transport.Pipes,
+ Thrift.Transport.WinHTTP,
+ Thrift.Transport.MsxmlHTTP,
Thrift.Transport,
Thrift.Stream,
Thrift.Test,
@@ -115,6 +117,7 @@
procedure InitializeProtocolTransportStack;
procedure ShutdownProtocolTransportStack;
+ function InitializeHttpTransport( const aTimeoutSetting : Integer) : IHTTPClient;
procedure JSONProtocolReadWriteTest;
function PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes;
@@ -188,7 +191,7 @@
+ ' instead of host and port'#10
+ ' --named-pipe arg Windows Named Pipe (e.g. MyThriftPipe)'#10
+ ' --anon-pipes hRead hWrite Windows Anonymous Pipes pair (handles)'#10
- + ' --transport arg (=sockets) Transport: buffered, framed, http, evhttp'#10
+ + ' --transport arg (=sockets) Transport: buffered, framed, http, winhttp'#10
+ ' --protocol arg (=binary) Protocol: binary, compact, json'#10
+ ' --ssl Encrypted Transport using SSL'#10
+ ' -n [ --testloops ] arg (=1) Number of Tests'#10
@@ -274,14 +277,15 @@
Console.WriteLine('Using anonymous pipes ('+IntToStr(Integer(setup.hAnonRead))+' and '+IntToStr(Integer(setup.hAnonWrite))+')');
end
else if s = '--transport' then begin
- // --transport arg (=sockets) Transport: buffered, framed, http, evhttp
+ // --transport arg (=sockets) Transport: buffered, framed, http, winhttp, evhttp
s := args[i];
Inc( i);
if s = 'buffered' then Include( setup.layered, trns_Buffered)
else if s = 'framed' then Include( setup.layered, trns_Framed)
- else if s = 'http' then setup.endpoint := trns_Http
- else if s = 'evhttp' then setup.endpoint := trns_EvHttp
+ else if s = 'http' then setup.endpoint := trns_MsXmlHttp
+ else if s = 'winhttp' then setup.endpoint := trns_WinHttp
+ else if s = 'evhttp' then setup.endpoint := trns_EvHttp // recognized, but not supported
else InvalidArgs;
end
else if s = '--protocol' then begin
@@ -1315,11 +1319,41 @@
end;
+function TClientThread.InitializeHttpTransport( const aTimeoutSetting : Integer) : IHTTPClient;
+var sUrl : string;
+begin
+ ASSERT( FSetup.endpoint in [trns_MsxmlHttp, trns_WinHttp]);
+
+ if FSetup.useSSL
+ then sUrl := 'https://'
+ else sUrl := 'http://';
+
+ sUrl := sUrl + FSetup.host;
+
+ case FSetup.port of
+ 80 : if FSetup.useSSL then sUrl := sUrl + ':'+ IntToStr(FSetup.port);
+ 443 : if not FSetup.useSSL then sUrl := sUrl + ':'+ IntToStr(FSetup.port);
+ else
+ if FSetup.port > 0 then sUrl := sUrl + ':'+ IntToStr(FSetup.port);
+ end;
+
+ Console.WriteLine('Target URL: '+sUrl);
+ case FSetup.endpoint of
+ trns_MsxmlHttp : result := TMsxmlHTTPClientImpl.Create( sUrl);
+ trns_WinHttp : result := TWinHTTPClientImpl.Create( sUrl);
+ else
+ raise Exception.Create(ENDPOINT_TRANSPORTS[FSetup.endpoint]+' unhandled case');
+ end;
+
+ result.DnsResolveTimeout := aTimeoutSetting;
+ result.ConnectionTimeout := aTimeoutSetting;
+ result.SendTimeout := aTimeoutSetting;
+ result.ReadTimeout := aTimeoutSetting;
+end;
+
+
procedure TClientThread.InitializeProtocolTransportStack;
-var
- streamtrans : IStreamTransport;
- http : IHTTPClient;
- sUrl : string;
+var streamtrans : IStreamTransport;
const
DEBUG_TIMEOUT = 30 * 1000;
RELEASE_TIMEOUT = DEFAULT_THRIFT_TIMEOUT;
@@ -1336,24 +1370,10 @@
FTransport := streamtrans;
end;
- trns_Http: begin
+ trns_MsxmlHttp,
+ trns_WinHttp: begin
Console.WriteLine('Using HTTPClient');
- if FSetup.useSSL
- then sUrl := 'http://'
- else sUrl := 'https://';
- sUrl := sUrl + FSetup.host;
- case FSetup.port of
- 80 : if FSetup.useSSL then sUrl := sUrl + ':'+ IntToStr(FSetup.port);
- 443 : if not FSetup.useSSL then sUrl := sUrl + ':'+ IntToStr(FSetup.port);
- else
- if FSetup.port > 0 then sUrl := sUrl + ':'+ IntToStr(FSetup.port);
- end;
- http := THTTPClientImpl.Create( sUrl);
- http.DnsResolveTimeout := HTTP_TIMEOUTS;
- http.ConnectionTimeout := HTTP_TIMEOUTS;
- http.SendTimeout := HTTP_TIMEOUTS;
- http.ReadTimeout := HTTP_TIMEOUTS;
- FTransport := http;
+ FTransport := InitializeHttpTransport( HTTP_TIMEOUTS);
end;
trns_EvHttp: begin
diff --git a/lib/delphi/test/TestConstants.pas b/lib/delphi/test/TestConstants.pas
index 37969dc..6bb20e9 100644
--- a/lib/delphi/test/TestConstants.pas
+++ b/lib/delphi/test/TestConstants.pas
@@ -39,7 +39,8 @@
TEndpointTransport = (
trns_Sockets,
- trns_Http,
+ trns_MsxmlHttp,
+ trns_WinHttp,
trns_NamedPipes,
trns_AnonPipes,
trns_EvHttp // as listed on http://thrift.apache.org/test
@@ -63,7 +64,7 @@
= ('Buffered', 'Framed');
ENDPOINT_TRANSPORTS : array[TEndpointTransport] of string
- = ('Sockets', 'Http', 'Named Pipes','Anon Pipes', 'EvHttp');
+ = ('Sockets', 'Http', 'WinHttp', 'Named Pipes','Anon Pipes', 'EvHttp');
// defaults are: read=false, write=true
BINARY_STRICT_READ = FALSE;
diff --git a/lib/delphi/test/TestServer.pas b/lib/delphi/test/TestServer.pas
index 69cb175..4cb0090 100644
--- a/lib/delphi/test/TestServer.pas
+++ b/lib/delphi/test/TestServer.pas
@@ -150,7 +150,7 @@
function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz;
begin
- Console.WriteLine('testEnum(' + IntToStr( Integer( thing)) + ')');
+ Console.WriteLine('testEnum(' + EnumUtils<TNumberz>.ToString(Ord(thing)) + ')');
Result := thing;
end;
@@ -191,7 +191,10 @@
insane : IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
begin
- Console.WriteLine('testInsanity()');
+ Console.Write('testInsanity(');
+ if argument <> nil then Console.Write(argument.ToString);
+ Console.WriteLine(')');
+
(**
* So you think you've got this all worked, out eh?
@@ -222,49 +225,20 @@
Result := insane;
end;
-function TTestServer.TTestHandlerImpl.testList(
- const thing: IThriftList<Integer>): IThriftList<Integer>;
-var
- first : Boolean;
- elem : Integer;
+function TTestServer.TTestHandlerImpl.testList( const thing: IThriftList<Integer>): IThriftList<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('})');
+ Console.Write('testList(');
+ if thing <> nil then Console.Write(thing.ToString);
+ Console.WriteLine(')');
Result := thing;
end;
function TTestServer.TTestHandlerImpl.testMap(
const 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('})');
+ Console.Write('testMap(');
+ if thing <> nil then Console.Write(thing.ToString);
+ Console.WriteLine(')');
Result := thing;
end;
@@ -313,12 +287,11 @@
x2 : TXception2;
begin
Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')');
- if ( arg0 = 'Xception') then
- begin
+ if ( arg0 = 'Xception') then begin
raise TXception.Create( 1001, 'This is an Xception'); // test the new rich CTOR
- end else
- if ( arg0 = 'Xception2') then
- begin
+ end;
+
+ if ( arg0 = 'Xception2') then begin
x2 := TXception2.Create; // the old way still works too?
x2.ErrorCode := 2002;
x2.Struct_thing := TXtructImpl.Create;
@@ -332,17 +305,11 @@
end;
function TTestServer.TTestHandlerImpl.testNest( const 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) + '})');
+ Console.Write('testNest(');
+ if thing <> nil then Console.Write(thing.ToString);
+ Console.WriteLine(')');
+
Result := thing;
end;
@@ -353,34 +320,18 @@
Console.WriteLine('testOneway finished');
end;
-function TTestServer.TTestHandlerImpl.testSet(
- const thing: IHashSet<Integer>):IHashSet<Integer>;
-var
- first : Boolean;
- elem : Integer;
+function TTestServer.TTestHandlerImpl.testSet( const thing: IHashSet<Integer>):IHashSet<Integer>;
begin
- Console.Write('testSet({');
- first := True;
+ Console.Write('testSet(');
+ if thing <> nil then Console.Write(thing.ToString);
+ Console.WriteLine(')');;
- 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
+ if FServer <> nil then begin
FServer.Stop;
end;
end;
@@ -399,24 +350,11 @@
function TTestServer.TTestHandlerImpl.testStringMap(
const thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
-var
- first : Boolean;
- key : string;
begin
- Console.Write('testStringMap({');
- first := True;
- for key in thing.Keys do
- begin
- if (first) then
- begin
- first := false;
- end else
- begin
- Console.Write(', ');
- end;
- Console.Write(key + ' => ' + thing[key]);
- end;
- Console.WriteLine('})');
+ Console.Write('testStringMap(');
+ if thing <> nil then Console.Write(thing.ToString);
+ Console.WriteLine(')');
+
Result := thing;
end;
@@ -433,11 +371,10 @@
function TTestServer.TTestHandlerImpl.testStruct( const thing: IXtruct): IXtruct;
begin
- Console.WriteLine('testStruct({' +
- '"' + thing.String_thing + '", ' +
- IntToStr( thing.Byte_thing) + ', ' +
- IntToStr( thing.I32_thing) + ', ' +
- IntToStr( thing.I64_thing));
+ Console.Write('testStruct(');
+ if thing <> nil then Console.Write(thing.ToString);
+ Console.WriteLine(')');
+
Result := thing;
end;
@@ -592,7 +529,8 @@
if s = 'buffered' then Include( layered, trns_Buffered)
else if s = 'framed' then Include( layered, trns_Framed)
- else if s = 'http' then endpoint := trns_Http
+ else if s = 'http' then endpoint := trns_MsxmlHttp
+ else if s = 'winhttp' then endpoint := trns_WinHttp
else if s = 'anonpipe' then endpoint := trns_AnonPipes
else InvalidArgs;
end
@@ -650,8 +588,9 @@
servertrans := TServerSocketImpl.Create( Port, 0, (trns_Buffered in layered));
end;
- trns_Http : begin
- raise Exception.Create(ENDPOINT_TRANSPORTS[endpoint]+' server transport not implemented');
+ trns_MsxmlHttp,
+ trns_WinHttp : begin
+ raise Exception.Create('HTTP server transport not implemented');
end;
trns_NamedPipes : begin
diff --git a/lib/delphi/test/client.dpr b/lib/delphi/test/client.dpr
index 06dbd3d..1d1607d 100644
--- a/lib/delphi/test/client.dpr
+++ b/lib/delphi/test/client.dpr
@@ -31,6 +31,8 @@
Thrift.Socket in '..\src\Thrift.Socket.pas',
Thrift.Exception in '..\src\Thrift.Exception.pas',
Thrift.Transport.Pipes in '..\src\Thrift.Transport.Pipes.pas',
+ Thrift.Transport.WinHTTP in '..\src\Thrift.Transport.WinHTTP.pas',
+ Thrift.Transport.MsxmlHTTP in '..\src\Thrift.Transport.MsxmlHTTP.pas',
Thrift.Protocol in '..\src\Thrift.Protocol.pas',
Thrift.Protocol.JSON in '..\src\Thrift.Protocol.JSON.pas',
Thrift.Protocol.Compact in '..\src\Thrift.Protocol.Compact.pas',
@@ -39,6 +41,7 @@
Thrift.Server in '..\src\Thrift.Server.pas',
Thrift.Stream in '..\src\Thrift.Stream.pas',
Thrift.TypeRegistry in '..\src\Thrift.TypeRegistry.pas',
+ Thrift.WinHTTP in '..\src\Thrift.WinHTTP.pas',
Thrift.Utils in '..\src\Thrift.Utils.pas';
var
diff --git a/lib/delphi/test/multiplexed/Multiplex.Test.Client.dpr b/lib/delphi/test/multiplexed/Multiplex.Test.Client.dpr
index 4278d8f..a57e93a 100644
--- a/lib/delphi/test/multiplexed/Multiplex.Test.Client.dpr
+++ b/lib/delphi/test/multiplexed/Multiplex.Test.Client.dpr
@@ -36,6 +36,7 @@
Thrift.Server in '..\..\src\Thrift.Server.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
+ Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas',
Thrift.Utils in '..\..\src\Thrift.Utils.pas';
var
diff --git a/lib/delphi/test/multiplexed/Multiplex.Test.Server.dpr b/lib/delphi/test/multiplexed/Multiplex.Test.Server.dpr
index 120462b..81ed3dd 100644
--- a/lib/delphi/test/multiplexed/Multiplex.Test.Server.dpr
+++ b/lib/delphi/test/multiplexed/Multiplex.Test.Server.dpr
@@ -36,6 +36,7 @@
Thrift.Collections in '..\..\src\Thrift.Collections.pas',
Thrift.Server in '..\..\src\Thrift.Server.pas',
Thrift.Utils in '..\..\src\Thrift.Utils.pas',
+ Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas';
diff --git a/lib/delphi/test/serializer/TestSerializer.dpr b/lib/delphi/test/serializer/TestSerializer.dpr
index 51e22a4..1f5ae8b 100644
--- a/lib/delphi/test/serializer/TestSerializer.dpr
+++ b/lib/delphi/test/serializer/TestSerializer.dpr
@@ -34,6 +34,7 @@
Thrift.Utils in '..\..\src\Thrift.Utils.pas',
Thrift.Serializer in '..\..\src\Thrift.Serializer.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas',
+ Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
System_,
DebugProtoTest,
diff --git a/lib/delphi/test/server.dpr b/lib/delphi/test/server.dpr
index b5e48a6..9731dd4 100644
--- a/lib/delphi/test/server.dpr
+++ b/lib/delphi/test/server.dpr
@@ -40,6 +40,7 @@
Thrift.Server in '..\src\Thrift.Server.pas',
Thrift.TypeRegistry in '..\src\Thrift.TypeRegistry.pas',
Thrift.Utils in '..\src\Thrift.Utils.pas',
+ Thrift.WinHTTP in '..\src\Thrift.WinHTTP.pas',
Thrift.Stream in '..\src\Thrift.Stream.pas';
var
diff --git a/lib/delphi/test/skip/skiptest_version1.dpr b/lib/delphi/test/skip/skiptest_version1.dpr
index 803d6bd..0bfe96f 100644
--- a/lib/delphi/test/skip/skiptest_version1.dpr
+++ b/lib/delphi/test/skip/skiptest_version1.dpr
@@ -33,6 +33,7 @@
Thrift.Collections in '..\..\src\Thrift.Collections.pas',
Thrift.Server in '..\..\src\Thrift.Server.pas',
Thrift.Utils in '..\..\src\Thrift.Utils.pas',
+ Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas';
diff --git a/lib/delphi/test/skip/skiptest_version2.dpr b/lib/delphi/test/skip/skiptest_version2.dpr
index 633b247..7893748 100644
--- a/lib/delphi/test/skip/skiptest_version2.dpr
+++ b/lib/delphi/test/skip/skiptest_version2.dpr
@@ -33,6 +33,7 @@
Thrift.Collections in '..\..\src\Thrift.Collections.pas',
Thrift.Server in '..\..\src\Thrift.Server.pas',
Thrift.Utils in '..\..\src\Thrift.Utils.pas',
+ Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas';
diff --git a/lib/delphi/test/typeregistry/TestTypeRegistry.dpr b/lib/delphi/test/typeregistry/TestTypeRegistry.dpr
index 18a7c7d..fd5e3dd 100644
--- a/lib/delphi/test/typeregistry/TestTypeRegistry.dpr
+++ b/lib/delphi/test/typeregistry/TestTypeRegistry.dpr
@@ -34,6 +34,7 @@
Thrift.Utils in '..\..\src\Thrift.Utils.pas',
Thrift.Serializer in '..\..\src\Thrift.Serializer.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas',
+ Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
DebugProtoTest;
diff --git a/lib/erl/Makefile.am b/lib/erl/Makefile.am
index 06323b4..d4544a3 100644
--- a/lib/erl/Makefile.am
+++ b/lib/erl/Makefile.am
@@ -49,13 +49,10 @@
touch .generated
all: .generated
- $(REBAR) get-deps
$(REBAR) compile
check: .generated
- $(REBAR) -C rebar.test.config get-deps
- $(REBAR) -C rebar.test.config compile
- $(REBAR) -C rebar.test.config skip_deps=true eunit
+ $(REBAR) eunit
install: all
mkdir -p $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift) ; \
@@ -67,16 +64,26 @@
done
uninstall:
- rm -rf $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift)
+ $(RM) -rf $(DESTDIR)$(ERLANG_INSTALL_LIB_DIR_thrift)
-clean:
- rm -f .generated
- rm -rf test/gen-erl/
- rm -f $(THRIFT_OMIT_FILE)
+clean-local:
$(REBAR) clean
+ $(RM) .generated
+ $(RM) -r .rebar/
+ $(RM) -r _build/
+ $(RM) -r test/gen-erl/
+ $(RM) $(THRIFT_OMIT_FILE)
maintainer-clean-local:
- rm -rf ebin
+ $(RM) -r ebin/
+
+dist-hook:
+ $(RM) $(distdir)/.generated
+ $(RM) -r $(distdir)/.rebar/
+ $(RM) -r $(distdir)/_build/
+ $(RM) -r $(distdir)/ebin/
+ $(RM) -r $(distdir)/test/gen-erl/
+ $(RM) $(distdir)/$(THRIFT_OMIT_FILE)
EXTRA_DIST = \
include \
@@ -84,7 +91,6 @@
coding_standards.md \
rebar.config \
rebar.config.script \
- rebar.test.config \
test \
README.md
diff --git a/lib/erl/rebar.config b/lib/erl/rebar.config
index 1ea18a4..1b32947 100644
--- a/lib/erl/rebar.config
+++ b/lib/erl/rebar.config
@@ -1 +1,3 @@
{erl_opts, [{platform_define, "^R.*", otp16_or_less}, debug_info]}.
+
+{profiles, [{test, [{deps, [meck]}]}]}.
diff --git a/lib/erl/rebar.test.config b/lib/erl/rebar.test.config
deleted file mode 100644
index 2ff2afb..0000000
--- a/lib/erl/rebar.test.config
+++ /dev/null
@@ -1,5 +0,0 @@
-{erl_opts, [{platform_define, "^R.*", otp16_or_less}, debug_info]}.
-
-{deps, [
- {meck, "", {git, "https://github.com/eproxus/meck.git", {tag, "0.8.9"}}}
-]}.
diff --git a/lib/erl/src/thrift.app.src b/lib/erl/src/thrift.app.src
index ce49f61..e5e6ed5 100644
--- a/lib/erl/src/thrift.app.src
+++ b/lib/erl/src/thrift.app.src
@@ -22,7 +22,7 @@
{description, "Thrift bindings"},
% The version of the applicaton
- {vsn, "0.12.1"},
+ {vsn, "0.13.0"},
% All modules used by the application.
{modules, [
diff --git a/lib/erl/src/thrift_socket_server.erl b/lib/erl/src/thrift_socket_server.erl
index 4e3c052..432e65b 100644
--- a/lib/erl/src/thrift_socket_server.erl
+++ b/lib/erl/src/thrift_socket_server.erl
@@ -278,9 +278,13 @@
terminate(Reason, #thrift_socket_server{listen=Listen, port=Port}) ->
gen_tcp:close(Listen),
- {backtrace, Bt} = erlang:process_info(self(), backtrace),
- error_logger:error_report({?MODULE, ?LINE,
- {child_error, Reason, Bt}}),
+ case Reason of
+ normal -> ok;
+ shutdown -> ok;
+ _ -> {backtrace, Bt} = erlang:process_info(self(), backtrace),
+ error_logger:error_report({?MODULE, ?LINE,
+ {child_error, Reason, Bt}})
+ end,
case Port < 1024 of
true ->
catch fdsrv:stop(),
diff --git a/lib/go/test/GoTagTest.thrift b/lib/go/test/GoTagTest.thrift
index 508b3b6..5667c6e 100644
--- a/lib/go/test/GoTagTest.thrift
+++ b/lib/go/test/GoTagTest.thrift
@@ -21,4 +21,5 @@
1: string string_thing,
2: i64 int_thing (go.tag = "json:\"int_thing,string\""),
3: optional i64 optional_int_thing
+ 4: optional bool optional_bool_thing = false
}
diff --git a/lib/go/test/tests/gotag_test.go b/lib/go/test/tests/gotag_test.go
index 32f056f..ff2f14e 100644
--- a/lib/go/test/tests/gotag_test.go
+++ b/lib/go/test/tests/gotag_test.go
@@ -51,3 +51,12 @@
t.Error("Unexpected default tag value for optional field")
}
}
+
+func TestOptionalTagWithDefaultValue(t *testing.T) {
+ s := gotagtest.Tagged{}
+ st := reflect.TypeOf(s)
+ field, ok := st.FieldByName("OptionalBoolThing")
+ if !ok || field.Tag.Get("json") != "optional_bool_thing" {
+ t.Error("Unexpected default tag value for optional field that has a default value")
+ }
+}
diff --git a/lib/go/thrift/serializer_types_test.go b/lib/go/thrift/serializer_types_test.go
index cb9f8b0..e5472bb 100644
--- a/lib/go/thrift/serializer_types_test.go
+++ b/lib/go/thrift/serializer_types_test.go
@@ -19,7 +19,7 @@
package thrift
-// Autogenerated by Thrift Compiler (0.12.1)
+// Autogenerated by Thrift Compiler (FIXME)
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
/* THE FOLLOWING THRIFT FILE WAS USED TO CREATE THIS
diff --git a/lib/go/thrift/socket.go b/lib/go/thrift/socket.go
index 8854279..88b98f5 100644
--- a/lib/go/thrift/socket.go
+++ b/lib/go/thrift/socket.go
@@ -162,5 +162,5 @@
func (p *TSocket) RemainingBytes() (num_bytes uint64) {
const maxSize = ^uint64(0)
- return maxSize // the thruth is, we just don't know unless framed is used
+ return maxSize // the truth is, we just don't know unless framed is used
}
diff --git a/lib/haxe/README.md b/lib/haxe/README.md
index 29f88a8..c9f74b5 100644
--- a/lib/haxe/README.md
+++ b/lib/haxe/README.md
@@ -69,14 +69,12 @@
Thrift Haxe bindings can be set up via the `haxelib` tool
either from the official ASF repo, or via the github mirror.
-- To set up any **stable version**, choose the appropriate branch (e.g. `0.10.0`):
+- To set up any **stable version**, choose the appropriate branch (e.g. `0.12.0`):
- - `haxelib git thrift https://git.apache.org/thrift.git 0.12.1 lib/haxe`
- - `haxelib git thrift https://github.com/apache/thrift.git 0.12.1 lib/haxe`
+ - `haxelib git thrift https://github.com/apache/thrift.git 0.12.0 lib/haxe`
- To set up the current **development version**, use the `master` branch:
- - `haxelib git thrift https://git.apache.org/thrift.git master lib/haxe`
- `haxelib git thrift https://github.com/apache/thrift.git master lib/haxe`
As usual, the installed library can be updated using `haxelib upgrade`
diff --git a/lib/haxe/haxelib.json b/lib/haxe/haxelib.json
index df107f9..b3c1530 100644
--- a/lib/haxe/haxelib.json
+++ b/lib/haxe/haxelib.json
@@ -4,7 +4,7 @@
"license": "Apache",
"tags": ["thrift", "rpc", "serialization", "cross", "framework"],
"description": "Haxe bindings for the Apache Thrift RPC and serialization framework",
- "version": "0.12.1",
+ "version": "0.13.0",
"releasenote": "Licensed under Apache License, Version 2.0. The Apache Thrift compiler needs to be installed separately.",
"contributors": ["Apache Software Foundation (ASF)"],
"dependencies": { },
diff --git a/lib/hs/CMakeLists.txt b/lib/hs/CMakeLists.txt
index a20a319..1a5b8fd 100644
--- a/lib/hs/CMakeLists.txt
+++ b/lib/hs/CMakeLists.txt
@@ -60,7 +60,7 @@
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(hs_optimize -O0)
-elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
+else()
set(hs_optimize -O1)
endif()
diff --git a/lib/hs/README.md b/lib/hs/README.md
index eea0a73..10bdeff 100644
--- a/lib/hs/README.md
+++ b/lib/hs/README.md
@@ -97,3 +97,17 @@
Just a function that takes a handler label, protocols. It calls the
superclasses process if there is a superclass.
+
+Releasing to Hackage
+====================
+
+Using the [Docker Container for Ubuntu Bionic](../../build/docker/README.md), run:
+
+ root@e941f5311545:/thrift/src# ./bootstrap.sh && ./configure
+ root@e941f5311545:/thrift/src# cd lib/hs && make dist-local
+
+This will produce a `lib/hs/dist/thrift-<version>.tar.gz` file. Take this
+file and upload it as a Haskell Hackage
+[package candidate](https://hackage.haskell.org/upload#candidates) and
+check to make sure all the information is correct. Assuming all is satisfactory,
+you can upload the package as official using the link at the top of the page.
diff --git a/lib/hs/thrift.cabal b/lib/hs/thrift.cabal
index cab9d1e..dd30d89 100644
--- a/lib/hs/thrift.cabal
+++ b/lib/hs/thrift.cabal
@@ -18,7 +18,7 @@
--
Name: thrift
-Version: 0.12.1
+Version: 0.13.0
Cabal-Version: 1.24
License: Apache
Category: Foreign
@@ -42,7 +42,7 @@
Build-Depends:
base >= 4, base < 5, containers, ghc-prim, attoparsec, binary, bytestring >= 0.10, base64-bytestring, hashable, HTTP, text, hspec-core > 2.4.0, unordered-containers >= 0.2.6, vector >= 0.10.12.2, QuickCheck >= 2.8.2, split
if flag(network-uri)
- build-depends: network-uri >= 2.6, network >= 2.6
+ build-depends: network-uri >= 2.6, network >= 2.6 && < 3.0
else
build-depends: network < 2.6
Exposed-Modules:
diff --git a/lib/java/README.md b/lib/java/README.md
index de515a5..7dca456 100644
--- a/lib/java/README.md
+++ b/lib/java/README.md
@@ -165,3 +165,21 @@
Gradle
http://gradle.org/
+
+# Breaking Changes
+
+## 1.0
+
+The signature of the 'process' method in TAsyncProcessor and TProcessor has
+changed to remove a boolean return type and to instead rely on Exceptions.
+
+## 0.12.0
+
+The access modifier of the AutoExpandingBuffer class has been changed from
+public to default (package) and will no longer be accessible by third-party
+libraries.
+
+The access modifier of the ShortStack class has been changed from
+public to default (package) and will no longer be accessible by third-party
+libraries.
+
diff --git a/lib/java/build.gradle b/lib/java/build.gradle
index d03b273..5f0d278 100644
--- a/lib/java/build.gradle
+++ b/lib/java/build.gradle
@@ -27,7 +27,7 @@
}
dependencies {
- classpath 'com.bmuschko:gradle-clover-plugin:2.2.0'
+ classpath 'com.bmuschko:gradle-clover-plugin:2.2.1'
}
}
@@ -35,7 +35,7 @@
id 'java'
id 'maven'
id 'signing'
- id 'com.github.johnrengelman.shadow' version '2.0.2'
+ id 'com.github.johnrengelman.shadow' version '4.0.4'
}
description = 'Apache Thrift Java Library'
diff --git a/lib/java/gradle.properties b/lib/java/gradle.properties
index 42c4010..0811659 100644
--- a/lib/java/gradle.properties
+++ b/lib/java/gradle.properties
@@ -1,7 +1,7 @@
# This file is shared currently between this Gradle build and the
# Ant builds for fd303 and JavaScript. Keep the dotted notation for
# the properties to minimize the changes in the dependencies.
-thrift.version=0.12.1
+thrift.version=0.13.0
thrift.groupid=org.apache.thrift
release=false
@@ -31,3 +31,4 @@
servlet.version=2.5
junit.version=4.12
mockito.version=1.9.5
+javax.annotation.version=1.3.2
diff --git a/lib/java/gradle/codeQualityChecks.gradle b/lib/java/gradle/codeQualityChecks.gradle
index 9572ca1..1ff1c29 100644
--- a/lib/java/gradle/codeQualityChecks.gradle
+++ b/lib/java/gradle/codeQualityChecks.gradle
@@ -28,7 +28,6 @@
ignoreFailures = true
toolVersion = '6.0.0'
sourceSets = [ sourceSets.main ]
- targetJdk = sourceCompatibility
ruleSets = [ 'java-basic' ]
}
diff --git a/lib/java/gradle/environment.gradle b/lib/java/gradle/environment.gradle
index 9b7eb1e..45fa63a 100644
--- a/lib/java/gradle/environment.gradle
+++ b/lib/java/gradle/environment.gradle
@@ -48,6 +48,7 @@
ext.slf4jVersion = property('slf4j.version')
ext.junitVersion = property('junit.version')
ext.mockitoVersion = property('mockito.version')
+ext.javaxAnnotationVersion = property('javax.annotation.version')
// In this section you declare where to find the dependencies of your project
repositories {
@@ -66,6 +67,7 @@
compile "org.apache.httpcomponents:httpclient:${httpclientVersion}"
compile "org.apache.httpcomponents:httpcore:${httpcoreVersion}"
compile "javax.servlet:servlet-api:${servletVersion}"
+ compile "javax.annotation:javax.annotation-api:${javaxAnnotationVersion}"
testCompile "junit:junit:${junitVersion}"
testCompile "org.mockito:mockito-all:${mockitoVersion}"
diff --git a/lib/java/gradle/sourceConfiguration.gradle b/lib/java/gradle/sourceConfiguration.gradle
index decc6a2..8dd0331 100644
--- a/lib/java/gradle/sourceConfiguration.gradle
+++ b/lib/java/gradle/sourceConfiguration.gradle
@@ -45,8 +45,8 @@
// ----------------------------------------------------------------------------
// Compiler configuration details
-sourceCompatibility = '1.6'
-targetCompatibility = '1.6'
+sourceCompatibility = '1.8'
+targetCompatibility = '1.8'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
diff --git a/lib/java/src/org/apache/thrift/Option.java b/lib/java/src/org/apache/thrift/Option.java
index db25ec5..d5cd309 100644
--- a/lib/java/src/org/apache/thrift/Option.java
+++ b/lib/java/src/org/apache/thrift/Option.java
@@ -24,6 +24,9 @@
*/
public abstract class Option<T> {
+ @SuppressWarnings("rawtypes")
+ private static final Option NONE = new None();
+
/**
* Whether the Option is defined or not
* @return
@@ -87,7 +90,7 @@
}
public String toString() {
- return "Some("+value.toString()+")";
+ return "Some(" + value + ")";
}
}
@@ -99,9 +102,9 @@
*/
public static <T> Option<T> fromNullable(T value) {
if (value != null) {
- return new Some<T>(value);
+ return some(value);
} else {
- return new None<T>();
+ return none();
}
}
@@ -115,7 +118,8 @@
return new Some<T>(value);
}
+ @SuppressWarnings("unchecked")
public static <T> None<T> none() {
- return new None<T>();
+ return (None<T>) NONE;
}
}
\ No newline at end of file
diff --git a/lib/java/src/org/apache/thrift/TAsyncProcessor.java b/lib/java/src/org/apache/thrift/TAsyncProcessor.java
index 533e74d..66f7688 100644
--- a/lib/java/src/org/apache/thrift/TAsyncProcessor.java
+++ b/lib/java/src/org/apache/thrift/TAsyncProcessor.java
@@ -21,8 +21,13 @@
import org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer;
public interface TAsyncProcessor {
- /**
- * Implementations must call fb.responseReady() once processing is complete
- */
- public boolean process(final AsyncFrameBuffer fb) throws TException;
+ /**
+ * Process a single frame.
+
+ * <b>Note:</b> Implementations must call fb.responseReady() once processing
+ * is complete
+ *
+ * @throws TException if the frame cannot be processed
+ */
+ public void process(final AsyncFrameBuffer fb) throws TException;
}
diff --git a/lib/java/src/org/apache/thrift/TBaseAsyncProcessor.java b/lib/java/src/org/apache/thrift/TBaseAsyncProcessor.java
index 9459c1a..f13f068 100644
--- a/lib/java/src/org/apache/thrift/TBaseAsyncProcessor.java
+++ b/lib/java/src/org/apache/thrift/TBaseAsyncProcessor.java
@@ -43,7 +43,7 @@
return Collections.unmodifiableMap(processMap);
}
- public boolean process(final AsyncFrameBuffer fb) throws TException {
+ public void process(final AsyncFrameBuffer fb) throws TException {
final TProtocol in = fb.getInputProtocol();
final TProtocol out = fb.getOutputProtocol();
@@ -54,15 +54,20 @@
if (fn == null) {
TProtocolUtil.skip(in, TType.STRUCT);
in.readMessageEnd();
- if (!fn.isOneway()) {
- TApplicationException x = new TApplicationException(TApplicationException.UNKNOWN_METHOD, "Invalid method name: '"+msg.name+"'");
+
+ TApplicationException x = new TApplicationException(TApplicationException.UNKNOWN_METHOD,
+ "Invalid method name: '" + msg.name + "'");
+ LOGGER.debug("Invalid method name", x);
+
+ // this means it is a two-way request, so we can send a reply
+ if (msg.type == TMessageType.CALL) {
out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));
x.write(out);
out.writeMessageEnd();
out.getTransport().flush();
}
fb.responseReady();
- return true;
+ return;
}
//Get Args
@@ -72,15 +77,19 @@
args.read(in);
} catch (TProtocolException e) {
in.readMessageEnd();
+
+ TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR,
+ e.getMessage());
+ LOGGER.debug("Could not retrieve function arguments", x);
+
if (!fn.isOneway()) {
- TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage());
out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));
x.write(out);
out.writeMessageEnd();
out.getTransport().flush();
}
fb.responseReady();
- return true;
+ return;
}
in.readMessageEnd();
@@ -93,13 +102,13 @@
try {
fn.start(iface, args, resultHandler);
} catch (Exception e) {
+ LOGGER.debug("Exception handling function", e);
resultHandler.onError(e);
}
- return true;
+ return;
}
@Override
- public boolean process(TProtocol in, TProtocol out) throws TException {
- return false;
+ public void process(TProtocol in, TProtocol out) throws TException {
}
}
diff --git a/lib/java/src/org/apache/thrift/TBaseHelper.java b/lib/java/src/org/apache/thrift/TBaseHelper.java
index 559df33..6f6c6eb 100644
--- a/lib/java/src/org/apache/thrift/TBaseHelper.java
+++ b/lib/java/src/org/apache/thrift/TBaseHelper.java
@@ -25,10 +25,11 @@
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
-import java.util.SortedSet;
import java.util.TreeMap;
-import java.util.TreeSet;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
public final class TBaseHelper {
@@ -53,57 +54,27 @@
}
public static int compareTo(boolean a, boolean b) {
- return Boolean.valueOf(a).compareTo(b);
+ return Boolean.compare(a, b);
}
public static int compareTo(byte a, byte b) {
- if (a < b) {
- return -1;
- } else if (b < a) {
- return 1;
- } else {
- return 0;
- }
+ return Byte.compare(a, b);
}
public static int compareTo(short a, short b) {
- if (a < b) {
- return -1;
- } else if (b < a) {
- return 1;
- } else {
- return 0;
- }
+ return Short.compare(a,b);
}
public static int compareTo(int a, int b) {
- if (a < b) {
- return -1;
- } else if (b < a) {
- return 1;
- } else {
- return 0;
- }
+ return Integer.compare(a, b);
}
public static int compareTo(long a, long b) {
- if (a < b) {
- return -1;
- } else if (b < a) {
- return 1;
- } else {
- return 0;
- }
+ return Long.compare(a, b);
}
public static int compareTo(double a, double b) {
- if (a < b) {
- return -1;
- } else if (b < a) {
- return 1;
- } else {
- return 0;
- }
+ return Double.compare(a, b);
}
public static int compareTo(String a, String b) {
@@ -111,17 +82,16 @@
}
public static int compareTo(byte[] a, byte[] b) {
- int sizeCompare = compareTo(a.length, b.length);
- if (sizeCompare != 0) {
- return sizeCompare;
- }
- for (int i = 0; i < a.length; i++) {
- int byteCompare = compareTo(a[i], b[i]);
- if (byteCompare != 0) {
- return byteCompare;
+ int compare = compareTo(a.length, b.length);
+ if (compare == 0) {
+ for (int i = 0; i < a.length; i++) {
+ compare = compareTo(a[i], b[i]);
+ if (compare != 0) {
+ break;
+ }
}
}
- return 0;
+ return compare;
}
public static int compareTo(Comparable a, Comparable b) {
@@ -129,41 +99,39 @@
}
public static int compareTo(List a, List b) {
- int lastComparison = compareTo(a.size(), b.size());
- if (lastComparison != 0) {
- return lastComparison;
- }
- for (int i = 0; i < a.size(); i++) {
- lastComparison = comparator.compare(a.get(i), b.get(i));
- if (lastComparison != 0) {
- return lastComparison;
+ int compare = compareTo(a.size(), b.size());
+ if (compare == 0) {
+ for (int i = 0; i < a.size(); i++) {
+ compare = comparator.compare(a.get(i), b.get(i));
+ if (compare != 0) {
+ break;
+ }
}
}
- return 0;
+ return compare;
}
public static int compareTo(Set a, Set b) {
- int lastComparison = compareTo(a.size(), b.size());
- if (lastComparison != 0) {
- return lastComparison;
- }
- SortedSet sortedA = new TreeSet(comparator);
- sortedA.addAll(a);
- SortedSet sortedB = new TreeSet(comparator);
- sortedB.addAll(b);
+ int compare = compareTo(a.size(), b.size());
+ if (compare == 0) {
+ ArrayList sortedA = new ArrayList(a);
+ ArrayList sortedB = new ArrayList(b);
- Iterator iterA = sortedA.iterator();
- Iterator iterB = sortedB.iterator();
+ Collections.sort(sortedA, comparator);
+ Collections.sort(sortedB, comparator);
- // Compare each item.
- while (iterA.hasNext() && iterB.hasNext()) {
- lastComparison = comparator.compare(iterA.next(), iterB.next());
- if (lastComparison != 0) {
- return lastComparison;
+ Iterator iterA = sortedA.iterator();
+ Iterator iterB = sortedB.iterator();
+
+ // Compare each item.
+ while (iterA.hasNext() && iterB.hasNext()) {
+ compare = comparator.compare(iterA.next(), iterB.next());
+ if (compare != 0) {
+ break;
+ }
}
}
-
- return 0;
+ return compare;
}
public static int compareTo(Map a, Map b) {
@@ -316,22 +284,14 @@
}
public static byte[] copyBinary(final byte[] orig) {
- if (orig == null) {
- return null;
- }
-
- byte[] copy = new byte[orig.length];
- System.arraycopy(orig, 0, copy, 0, orig.length);
- return copy;
+ return (orig == null) ? null : Arrays.copyOf(orig, orig.length);
}
public static int hashCode(long value) {
- int low = (int) value;
- int high = (int) (value >>> 32);
- return high * 127 + low;
+ return Long.hashCode(value);
}
public static int hashCode(double value) {
- return hashCode(Double.doubleToRawLongBits(value));
+ return Double.hashCode(value);
}
}
diff --git a/lib/java/src/org/apache/thrift/TBaseProcessor.java b/lib/java/src/org/apache/thrift/TBaseProcessor.java
index f9a9a9e..55a0f15 100644
--- a/lib/java/src/org/apache/thrift/TBaseProcessor.java
+++ b/lib/java/src/org/apache/thrift/TBaseProcessor.java
@@ -23,7 +23,7 @@
}
@Override
- public boolean process(TProtocol in, TProtocol out) throws TException {
+ public void process(TProtocol in, TProtocol out) throws TException {
TMessage msg = in.readMessageBegin();
ProcessFunction fn = processMap.get(msg.name);
if (fn == null) {
@@ -34,9 +34,8 @@
x.write(out);
out.writeMessageEnd();
out.getTransport().flush();
- return true;
+ } else {
+ fn.process(msg.seqid, in, out, iface);
}
- fn.process(msg.seqid, in, out, iface);
- return true;
}
}
diff --git a/lib/java/src/org/apache/thrift/TByteArrayOutputStream.java b/lib/java/src/org/apache/thrift/TByteArrayOutputStream.java
index 1c37ecd..3a2d56c 100644
--- a/lib/java/src/org/apache/thrift/TByteArrayOutputStream.java
+++ b/lib/java/src/org/apache/thrift/TByteArrayOutputStream.java
@@ -20,6 +20,7 @@
package org.apache.thrift;
import java.io.ByteArrayOutputStream;
+import java.nio.charset.Charset;
/**
* Class that allows access to the underlying buf without doing deep
@@ -53,4 +54,8 @@
public int len() {
return count;
}
+
+ public String toString(Charset charset) {
+ return new String(buf, 0, count, charset);
+ }
}
diff --git a/lib/java/src/org/apache/thrift/TDeserializer.java b/lib/java/src/org/apache/thrift/TDeserializer.java
index bf6c97c..d1d3966 100644
--- a/lib/java/src/org/apache/thrift/TDeserializer.java
+++ b/lib/java/src/org/apache/thrift/TDeserializer.java
@@ -251,48 +251,31 @@
try {
TField field = locateField(bytes, fieldIdPathFirst, fieldIdPathRest);
if (field != null) {
- // if this point is reached, iprot will be positioned at the start of the field.
- switch(ttype){
+ if (ttype == field.type) {
+ // if this point is reached, iprot will be positioned at the start of
+ // the field
+ switch (ttype) {
case TType.BOOL:
- if (field.type == TType.BOOL){
- return protocol_.readBool();
- }
- break;
+ return protocol_.readBool();
case TType.BYTE:
- if (field.type == TType.BYTE) {
- return protocol_.readByte();
- }
- break;
+ return protocol_.readByte();
case TType.DOUBLE:
- if (field.type == TType.DOUBLE) {
- return protocol_.readDouble();
- }
- break;
+ return protocol_.readDouble();
case TType.I16:
- if (field.type == TType.I16) {
- return protocol_.readI16();
- }
- break;
+ return protocol_.readI16();
case TType.I32:
- if (field.type == TType.I32) {
- return protocol_.readI32();
- }
- break;
+ return protocol_.readI32();
case TType.I64:
- if (field.type == TType.I64) {
- return protocol_.readI64();
- }
- break;
+ return protocol_.readI64();
case TType.STRING:
- if (field.type == TType.STRING) {
- return protocol_.readString();
- }
- break;
- case 100: // hack to differentiate between string and binary
- if (field.type == TType.STRING) {
- return protocol_.readBinary();
- }
- break;
+ return protocol_.readString();
+ default:
+ return null;
+ }
+ }
+ // hack to differentiate between string and binary
+ if (ttype == 100 && field.type == TType.STRING) {
+ return protocol_.readBinary();
}
}
return null;
@@ -307,11 +290,9 @@
private TField locateField(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException {
trans_.reset(bytes);
- TFieldIdEnum[] fieldIdPath= new TFieldIdEnum[fieldIdPathRest.length + 1];
+ TFieldIdEnum[] fieldIdPath = new TFieldIdEnum[fieldIdPathRest.length + 1];
fieldIdPath[0] = fieldIdPathFirst;
- for (int i = 0; i < fieldIdPathRest.length; i++){
- fieldIdPath[i + 1] = fieldIdPathRest[i];
- }
+ System.arraycopy(fieldIdPathRest, 0, fieldIdPath, 1, fieldIdPathRest.length);
// index into field ID path being currently searched for
int curPathIndex = 0;
diff --git a/lib/java/src/org/apache/thrift/TMultiplexedProcessor.java b/lib/java/src/org/apache/thrift/TMultiplexedProcessor.java
index d0c5603..c494862 100644
--- a/lib/java/src/org/apache/thrift/TMultiplexedProcessor.java
+++ b/lib/java/src/org/apache/thrift/TMultiplexedProcessor.java
@@ -87,12 +87,12 @@
* that allows readMessageBegin() to return the original TMessage.</li>
* </ol>
*
- * @throws TException If the message type is not CALL or ONEWAY, if
+ * @throws TProtocolException If the message type is not CALL or ONEWAY, if
* the service name was not found in the message, or if the service
* name was not found in the service map. You called {@link #registerProcessor(String, TProcessor) registerProcessor}
* during initialization, right? :)
*/
- public boolean process(TProtocol iprot, TProtocol oprot) throws TException {
+ public void process(TProtocol iprot, TProtocol oprot) throws TException {
/*
Use the actual underlying protocol (e.g. TBinaryProtocol) to read the
message header. This pulls the message "off the wire", which we'll
@@ -101,7 +101,8 @@
TMessage message = iprot.readMessageBegin();
if (message.type != TMessageType.CALL && message.type != TMessageType.ONEWAY) {
- throw new TException("This should not have happened!?");
+ throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED,
+ "This should not have happened!?");
}
// Extract the service name
@@ -109,18 +110,21 @@
if (index < 0) {
if (defaultProcessor != null) {
// Dispatch processing to the stored processor
- return defaultProcessor.process(new StoredMessageProtocol(iprot, message), oprot);
+ defaultProcessor.process(new StoredMessageProtocol(iprot, message), oprot);
+ return;
}
- throw new TException("Service name not found in message name: " + message.name + ". Did you " +
- "forget to use a TMultiplexProtocol in your client?");
+ throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED,
+ "Service name not found in message name: " + message.name + ". Did you " +
+ "forget to use a TMultiplexProtocol in your client?");
}
// Create a new TMessage, something that can be consumed by any TProtocol
String serviceName = message.name.substring(0, index);
TProcessor actualProcessor = SERVICE_PROCESSOR_MAP.get(serviceName);
if (actualProcessor == null) {
- throw new TException("Service name not found: " + serviceName + ". Did you forget " +
- "to call registerProcessor()?");
+ throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED,
+ "Service name not found: " + serviceName + ". Did you forget " +
+ "to call registerProcessor()?");
}
// Create a new TMessage, removing the service name
@@ -131,7 +135,7 @@
);
// Dispatch processing to the stored processor
- return actualProcessor.process(new StoredMessageProtocol(iprot, standardMessage), oprot);
+ actualProcessor.process(new StoredMessageProtocol(iprot, standardMessage), oprot);
}
/**
diff --git a/lib/java/src/org/apache/thrift/TProcessor.java b/lib/java/src/org/apache/thrift/TProcessor.java
index d79522c..15ba9c0 100644
--- a/lib/java/src/org/apache/thrift/TProcessor.java
+++ b/lib/java/src/org/apache/thrift/TProcessor.java
@@ -24,9 +24,7 @@
/**
* A processor is a generic object which operates upon an input stream and
* writes to some output stream.
- *
*/
public interface TProcessor {
- public boolean process(TProtocol in, TProtocol out)
- throws TException;
+ public void process(TProtocol in, TProtocol out) throws TException;
}
diff --git a/lib/java/src/org/apache/thrift/TUnion.java b/lib/java/src/org/apache/thrift/TUnion.java
index 13f9c67..1ef11df 100644
--- a/lib/java/src/org/apache/thrift/TUnion.java
+++ b/lib/java/src/org/apache/thrift/TUnion.java
@@ -79,7 +79,7 @@
}
private static Map deepCopyMap(Map<Object, Object> map) {
- Map copy = new HashMap();
+ Map copy = new HashMap(map.size());
for (Map.Entry<Object, Object> entry : map.entrySet()) {
copy.put(deepCopyObject(entry.getKey()), deepCopyObject(entry.getValue()));
}
@@ -87,7 +87,7 @@
}
private static Set deepCopySet(Set set) {
- Set copy = new HashSet();
+ Set copy = new HashSet(set.size());
for (Object o : set) {
copy.add(deepCopyObject(o));
}
diff --git a/lib/java/src/org/apache/thrift/ShortStack.java b/lib/java/src/org/apache/thrift/protocol/ShortStack.java
similarity index 74%
rename from lib/java/src/org/apache/thrift/ShortStack.java
rename to lib/java/src/org/apache/thrift/protocol/ShortStack.java
index 4957d1c..9e65930 100644
--- a/lib/java/src/org/apache/thrift/ShortStack.java
+++ b/lib/java/src/org/apache/thrift/protocol/ShortStack.java
@@ -16,45 +16,43 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.thrift;
+package org.apache.thrift.protocol;
+
+import java.util.Arrays;
/**
* ShortStack is a short-specific Stack implementation written for the express
* purpose of very fast operations on TCompactProtocol's field id stack. This
* implementation performs at least 10x faster than java.util.Stack.
*/
-public class ShortStack {
+class ShortStack {
private short[] vector;
- private int top = -1;
+
+ /** Always points to the next location */
+ private int top = 0;
public ShortStack(int initialCapacity) {
vector = new short[initialCapacity];
}
public short pop() {
- return vector[top--];
+ return vector[--top];
}
public void push(short pushed) {
- if (vector.length == top + 1) {
+ if (vector.length == top) {
grow();
}
- vector[++top] = pushed;
+ vector[top++] = pushed;
}
private void grow() {
- short[] newVector = new short[vector.length * 2];
- System.arraycopy(vector, 0, newVector, 0, vector.length);
- vector = newVector;
- }
-
- public short peek() {
- return vector[top];
+ vector = Arrays.copyOf(vector, vector.length << 1);
}
public void clear() {
- top = -1;
+ top = 0;
}
@Override
@@ -62,18 +60,15 @@
StringBuilder sb = new StringBuilder();
sb.append("<ShortStack vector:[");
for (int i = 0; i < vector.length; i++) {
+ boolean isTop = (i == (top - 1));
+ short value = vector[i];
if (i != 0) {
- sb.append(" ");
+ sb.append(' ');
}
-
- if (i == top) {
- sb.append(">>");
- }
-
- sb.append(vector[i]);
-
- if (i == top) {
- sb.append("<<");
+ if (isTop) {
+ sb.append(">>").append(value).append("<<");
+ } else {
+ sb.append(value);
}
}
sb.append("]>");
diff --git a/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java b/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java
index aaa1fd8..7924e2f 100644
--- a/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java
@@ -19,8 +19,8 @@
package org.apache.thrift.protocol;
-import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransport;
@@ -110,6 +110,7 @@
strictWrite_ = strictWrite;
}
+ @Override
public void writeMessageBegin(TMessage message) throws TException {
if (strictWrite_) {
int version = VERSION_1 | message.type;
@@ -123,60 +124,76 @@
}
}
- public void writeMessageEnd() {}
+ @Override
+ public void writeMessageEnd() throws TException {}
- public void writeStructBegin(TStruct struct) {}
+ @Override
+ public void writeStructBegin(TStruct struct) throws TException {}
- public void writeStructEnd() {}
+ @Override
+ public void writeStructEnd() throws TException {}
+ @Override
public void writeFieldBegin(TField field) throws TException {
writeByte(field.type);
writeI16(field.id);
}
- public void writeFieldEnd() {}
+ @Override
+ public void writeFieldEnd() throws TException {}
+ @Override
public void writeFieldStop() throws TException {
writeByte(TType.STOP);
}
+ @Override
public void writeMapBegin(TMap map) throws TException {
writeByte(map.keyType);
writeByte(map.valueType);
writeI32(map.size);
}
- public void writeMapEnd() {}
+ @Override
+ public void writeMapEnd() throws TException {}
+ @Override
public void writeListBegin(TList list) throws TException {
writeByte(list.elemType);
writeI32(list.size);
}
- public void writeListEnd() {}
+ @Override
+ public void writeListEnd() throws TException {}
+ @Override
public void writeSetBegin(TSet set) throws TException {
writeByte(set.elemType);
writeI32(set.size);
}
- public void writeSetEnd() {}
+ @Override
+ public void writeSetEnd() throws TException {}
+ @Override
public void writeBool(boolean b) throws TException {
writeByte(b ? (byte)1 : (byte)0);
}
+ @Override
public void writeByte(byte b) throws TException {
inoutTemp[0] = b;
trans_.write(inoutTemp, 0, 1);
}
+ @Override
public void writeI16(short i16) throws TException {
inoutTemp[0] = (byte)(0xff & (i16 >> 8));
inoutTemp[1] = (byte)(0xff & (i16));
trans_.write(inoutTemp, 0, 2);
}
+ @Override
public void writeI32(int i32) throws TException {
inoutTemp[0] = (byte)(0xff & (i32 >> 24));
inoutTemp[1] = (byte)(0xff & (i32 >> 16));
@@ -185,6 +202,7 @@
trans_.write(inoutTemp, 0, 4);
}
+ @Override
public void writeI64(long i64) throws TException {
inoutTemp[0] = (byte)(0xff & (i64 >> 56));
inoutTemp[1] = (byte)(0xff & (i64 >> 48));
@@ -197,20 +215,19 @@
trans_.write(inoutTemp, 0, 8);
}
+ @Override
public void writeDouble(double dub) throws TException {
writeI64(Double.doubleToLongBits(dub));
}
+ @Override
public void writeString(String str) throws TException {
- try {
- byte[] dat = str.getBytes("UTF-8");
- writeI32(dat.length);
- trans_.write(dat, 0, dat.length);
- } catch (UnsupportedEncodingException uex) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ byte[] dat = str.getBytes(StandardCharsets.UTF_8);
+ writeI32(dat.length);
+ trans_.write(dat, 0, dat.length);
}
+ @Override
public void writeBinary(ByteBuffer bin) throws TException {
int length = bin.limit() - bin.position();
writeI32(length);
@@ -221,6 +238,7 @@
* Reading methods.
*/
+ @Override
public TMessage readMessageBegin() throws TException {
int size = readI32();
if (size < 0) {
@@ -237,50 +255,63 @@
}
}
- public void readMessageEnd() {}
+ @Override
+ public void readMessageEnd() throws TException {}
- public TStruct readStructBegin() {
+ @Override
+ public TStruct readStructBegin() throws TException {
return ANONYMOUS_STRUCT;
}
- public void readStructEnd() {}
+ @Override
+ public void readStructEnd() throws TException {}
+ @Override
public TField readFieldBegin() throws TException {
byte type = readByte();
short id = type == TType.STOP ? 0 : readI16();
return new TField("", type, id);
}
- public void readFieldEnd() {}
+ @Override
+ public void readFieldEnd() throws TException {}
+ @Override
public TMap readMapBegin() throws TException {
TMap map = new TMap(readByte(), readByte(), readI32());
checkContainerReadLength(map.size);
return map;
}
- public void readMapEnd() {}
+ @Override
+ public void readMapEnd() throws TException {}
+ @Override
public TList readListBegin() throws TException {
TList list = new TList(readByte(), readI32());
checkContainerReadLength(list.size);
return list;
}
- public void readListEnd() {}
+ @Override
+ public void readListEnd() throws TException {}
+ @Override
public TSet readSetBegin() throws TException {
TSet set = new TSet(readByte(), readI32());
checkContainerReadLength(set.size);
return set;
}
- public void readSetEnd() {}
+ @Override
+ public void readSetEnd() throws TException {}
+ @Override
public boolean readBool() throws TException {
return (readByte() == 1);
}
+ @Override
public byte readByte() throws TException {
if (trans_.getBytesRemainingInBuffer() >= 1) {
byte b = trans_.getBuffer()[trans_.getBufferPosition()];
@@ -291,6 +322,7 @@
return inoutTemp[0];
}
+ @Override
public short readI16() throws TException {
byte[] buf = inoutTemp;
int off = 0;
@@ -309,6 +341,7 @@
((buf[off+1] & 0xff)));
}
+ @Override
public int readI32() throws TException {
byte[] buf = inoutTemp;
int off = 0;
@@ -327,6 +360,7 @@
((buf[off+3] & 0xff));
}
+ @Override
public long readI64() throws TException {
byte[] buf = inoutTemp;
int off = 0;
@@ -350,23 +384,22 @@
((long)(buf[off+7] & 0xff));
}
+ @Override
public double readDouble() throws TException {
return Double.longBitsToDouble(readI64());
}
+ @Override
public String readString() throws TException {
int size = readI32();
checkStringReadLength(size);
if (trans_.getBytesRemainingInBuffer() >= size) {
- try {
- String s = new String(trans_.getBuffer(), trans_.getBufferPosition(), size, "UTF-8");
- trans_.consumeBuffer(size);
- return s;
- } catch (UnsupportedEncodingException e) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ String s = new String(trans_.getBuffer(), trans_.getBufferPosition(),
+ size, StandardCharsets.UTF_8);
+ trans_.consumeBuffer(size);
+ return s;
}
return readStringBody(size);
@@ -374,15 +407,12 @@
public String readStringBody(int size) throws TException {
checkStringReadLength(size);
- try {
- byte[] buf = new byte[size];
- trans_.readAll(buf, 0, size);
- return new String(buf, "UTF-8");
- } catch (UnsupportedEncodingException uex) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ byte[] buf = new byte[size];
+ trans_.readAll(buf, 0, size);
+ return new String(buf, StandardCharsets.UTF_8);
}
+ @Override
public ByteBuffer readBinary() throws TException {
int size = readI32();
diff --git a/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java b/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java
index 56c349a..ee05869 100644
--- a/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java
@@ -22,8 +22,8 @@
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
-import org.apache.thrift.ShortStack;
import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransport;
@@ -202,6 +202,7 @@
* Write a message header to the wire. Compact Protocol messages contain the
* protocol version so we can migrate forwards in the future if need be.
*/
+ @Override
public void writeMessageBegin(TMessage message) throws TException {
writeByteDirect(PROTOCOL_ID);
writeByteDirect((VERSION & VERSION_MASK) | ((message.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK));
@@ -214,6 +215,7 @@
* use it as an opportunity to put special placeholder markers on the field
* stack so we can get the field id deltas correct.
*/
+ @Override
public void writeStructBegin(TStruct struct) throws TException {
lastField_.push(lastFieldId_);
lastFieldId_ = 0;
@@ -359,12 +361,8 @@
* Write a string to the wire with a varint size preceding.
*/
public void writeString(String str) throws TException {
- try {
- byte[] bytes = str.getBytes("UTF-8");
- writeBinary(bytes, 0, bytes.length);
- } catch (UnsupportedEncodingException e) {
- throw new TException("UTF-8 not supported!");
- }
+ byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
+ writeBinary(bytes, 0, bytes.length);
}
/**
@@ -680,17 +678,15 @@
return "";
}
- try {
- if (trans_.getBytesRemainingInBuffer() >= length) {
- String str = new String(trans_.getBuffer(), trans_.getBufferPosition(), length, "UTF-8");
- trans_.consumeBuffer(length);
- return str;
- } else {
- return new String(readBinary(length), "UTF-8");
- }
- } catch (UnsupportedEncodingException e) {
- throw new TException("UTF-8 not supported!");
+ final String str;
+ if (trans_.getBytesRemainingInBuffer() >= length) {
+ str = new String(trans_.getBuffer(), trans_.getBufferPosition(),
+ length, StandardCharsets.UTF_8);
+ trans_.consumeBuffer(length);
+ } else {
+ str = new String(readBinary(length), StandardCharsets.UTF_8);
}
+ return str;
}
/**
diff --git a/lib/java/src/org/apache/thrift/protocol/TField.java b/lib/java/src/org/apache/thrift/protocol/TField.java
index 31331bb..3872b00 100644
--- a/lib/java/src/org/apache/thrift/protocol/TField.java
+++ b/lib/java/src/org/apache/thrift/protocol/TField.java
@@ -21,7 +21,7 @@
/**
* Helper class that encapsulates field metadata.
- *
+ * <p>Two fields are considered equal if they have the same type and id.</p>
*/
public class TField {
public TField() {
@@ -47,7 +47,6 @@
final int prime = 31;
int result = 1;
result = prime * result + id;
- result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + type;
return result;
}
diff --git a/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java b/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java
index fd54fdf..d37c493 100644
--- a/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java
@@ -20,8 +20,8 @@
package org.apache.thrift.protocol;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Stack;
@@ -418,12 +418,8 @@
if (escapeNum) {
trans_.write(QUOTE);
}
- try {
- byte[] buf = str.getBytes("UTF-8");
- trans_.write(buf);
- } catch (UnsupportedEncodingException uex) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ byte[] buf = str.getBytes(StandardCharsets.UTF_8);
+ trans_.write(buf);
if (escapeNum) {
trans_.write(QUOTE);
}
@@ -453,12 +449,8 @@
if (escapeNum) {
trans_.write(QUOTE);
}
- try {
- byte[] b = str.getBytes("UTF-8");
- trans_.write(b, 0, b.length);
- } catch (UnsupportedEncodingException uex) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ byte[] b = str.getBytes(StandardCharsets.UTF_8);
+ trans_.write(b, 0, b.length);
if (escapeNum) {
trans_.write(QUOTE);
}
@@ -513,12 +505,8 @@
resetContext(); // THRIFT-3743
writeJSONArrayStart();
writeJSONInteger(VERSION);
- try {
- byte[] b = message.name.getBytes("UTF-8");
- writeJSONString(b);
- } catch (UnsupportedEncodingException uex) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ byte[] b = message.name.getBytes(StandardCharsets.UTF_8);
+ writeJSONString(b);
writeJSONInteger(message.type);
writeJSONInteger(message.seqid);
}
@@ -628,12 +616,8 @@
@Override
public void writeString(String str) throws TException {
- try {
- byte[] b = str.getBytes("UTF-8");
- writeJSONString(b);
- } catch (UnsupportedEncodingException uex) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ byte[] b = str.getBytes(StandardCharsets.UTF_8);
+ writeJSONString(b);
}
@Override
@@ -684,19 +668,17 @@
}
codeunits.add((char)cu);
- arr.write((new String(new int[] { codeunits.get(0), codeunits.get(1) }, 0, 2)).getBytes("UTF-8"));
+ arr.write(
+ (new String(new int[] { codeunits.get(0), codeunits.get(1) },
+ 0, 2)).getBytes(StandardCharsets.UTF_8));
codeunits.clear();
}
else {
- arr.write((new String(new int[] { cu }, 0, 1)).getBytes("UTF-8"));
+ arr.write((new String(new int[] { cu }, 0, 1))
+ .getBytes(StandardCharsets.UTF_8));
}
continue;
- }
- catch (UnsupportedEncodingException ex) {
- throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED,
- "JVM does not support UTF-8");
- }
- catch (IOException ex) {
+ } catch (IOException ex) {
throw new TProtocolException(TProtocolException.INVALID_DATA,
"Invalid unicode sequence");
}
@@ -777,19 +759,14 @@
context_.read();
if (reader_.peek() == QUOTE[0]) {
TByteArrayOutputStream arr = readJSONString(true);
- try {
- double dub = Double.valueOf(arr.toString("UTF-8"));
- if (!context_.escapeNum() && !Double.isNaN(dub) &&
- !Double.isInfinite(dub)) {
- // Throw exception -- we should not be in a string in this case
- throw new TProtocolException(TProtocolException.INVALID_DATA,
- "Numeric data unexpectedly quoted");
- }
- return dub;
+ double dub = Double.valueOf(arr.toString(StandardCharsets.UTF_8));
+ if (!context_.escapeNum() && !Double.isNaN(dub)
+ && !Double.isInfinite(dub)) {
+ // Throw exception -- we should not be in a string in this case
+ throw new TProtocolException(TProtocolException.INVALID_DATA,
+ "Numeric data unexpectedly quoted");
}
- catch (UnsupportedEncodingException ex) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ return dub;
}
else {
if (context_.escapeNum()) {
@@ -868,13 +845,7 @@
throw new TProtocolException(TProtocolException.BAD_VERSION,
"Message contained bad version.");
}
- String name;
- try {
- name = readJSONString(false).toString("UTF-8");
- }
- catch (UnsupportedEncodingException ex) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ String name = readJSONString(false).toString(StandardCharsets.UTF_8);
byte type = (byte) readJSONInteger();
int seqid = (int) readJSONInteger();
return new TMessage(name, type, seqid);
@@ -991,12 +962,7 @@
@Override
public String readString() throws TException {
- try {
- return readJSONString(false).toString("UTF-8");
- }
- catch (UnsupportedEncodingException ex) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ return readJSONString(false).toString(StandardCharsets.UTF_8);
}
@Override
diff --git a/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java b/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java
index b24e421..eb7e23b 100644
--- a/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java
@@ -19,8 +19,8 @@
package org.apache.thrift.protocol;
-import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import java.util.Stack;
import org.apache.thrift.TException;
@@ -167,6 +167,7 @@
super(trans);
}
+ @Override
public void writeMessageBegin(TMessage message) throws TException {
resetWriteContext(); // THRIFT-3743
trans_.write(LBRACKET);
@@ -176,31 +177,38 @@
writeI32(message.seqid);
}
+ @Override
public void writeMessageEnd() throws TException {
popWriteContext();
trans_.write(RBRACKET);
}
+ @Override
public void writeStructBegin(TStruct struct) throws TException {
writeContext_.write();
trans_.write(LBRACE);
pushWriteContext(new StructContext());
}
+ @Override
public void writeStructEnd() throws TException {
popWriteContext();
trans_.write(RBRACE);
}
+ @Override
public void writeFieldBegin(TField field) throws TException {
// Note that extra type information is omitted in JSON!
writeString(field.name);
}
- public void writeFieldEnd() {}
+ @Override
+ public void writeFieldEnd() throws TException {}
- public void writeFieldStop() {}
+ @Override
+ public void writeFieldStop() throws TException {}
+ @Override
public void writeMapBegin(TMap map) throws TException {
assertContextIsNotMapKey(MAP);
writeContext_.write();
@@ -209,11 +217,13 @@
// No metadata!
}
+ @Override
public void writeMapEnd() throws TException {
popWriteContext();
trans_.write(RBRACE);
}
+ @Override
public void writeListBegin(TList list) throws TException {
assertContextIsNotMapKey(LIST);
writeContext_.write();
@@ -222,11 +232,13 @@
// No metadata!
}
+ @Override
public void writeListEnd() throws TException {
popWriteContext();
trans_.write(RBRACKET);
}
+ @Override
public void writeSetBegin(TSet set) throws TException {
assertContextIsNotMapKey(SET);
writeContext_.write();
@@ -235,23 +247,28 @@
// No metadata!
}
+ @Override
public void writeSetEnd() throws TException {
popWriteContext();
trans_.write(RBRACKET);
}
+ @Override
public void writeBool(boolean b) throws TException {
writeByte(b ? (byte)1 : (byte)0);
}
+ @Override
public void writeByte(byte b) throws TException {
writeI32(b);
}
+ @Override
public void writeI16(short i16) throws TException {
writeI32(i16);
}
+ @Override
public void writeI32(int i32) throws TException {
if(writeContext_.isMapKey()) {
writeString(Integer.toString(i32));
@@ -262,14 +279,11 @@
}
public void _writeStringData(String s) throws TException {
- try {
- byte[] b = s.getBytes("UTF-8");
- trans_.write(b);
- } catch (UnsupportedEncodingException uex) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ byte[] b = s.getBytes(StandardCharsets.UTF_8);
+ trans_.write(b);
}
+ @Override
public void writeI64(long i64) throws TException {
if(writeContext_.isMapKey()) {
writeString(Long.toString(i64));
@@ -279,6 +293,7 @@
}
}
+ @Override
public void writeDouble(double dub) throws TException {
if(writeContext_.isMapKey()) {
writeString(Double.toString(dub));
@@ -288,6 +303,7 @@
}
}
+ @Override
public void writeString(String str) throws TException {
writeContext_.write();
int length = str.length();
@@ -341,90 +357,108 @@
_writeStringData(escape.toString());
}
+ @Override
public void writeBinary(ByteBuffer bin) throws TException {
- try {
- // TODO(mcslee): Fix this
- writeString(new String(bin.array(), bin.position() + bin.arrayOffset(), bin.limit() - bin.position() - bin.arrayOffset(), "UTF-8"));
- } catch (UnsupportedEncodingException uex) {
- throw new TException("JVM DOES NOT SUPPORT UTF-8");
- }
+ // TODO(mcslee): Fix this
+ writeString(new String(bin.array(), bin.position() + bin.arrayOffset(),
+ bin.limit() - bin.position() - bin.arrayOffset(),
+ StandardCharsets.UTF_8));
}
/**
* Reading methods.
*/
+ @Override
public TMessage readMessageBegin() throws TException {
// TODO(mcslee): implement
return EMPTY_MESSAGE;
}
- public void readMessageEnd() {}
+ @Override
+ public void readMessageEnd() throws TException {}
- public TStruct readStructBegin() {
+ @Override
+ public TStruct readStructBegin() throws TException {
// TODO(mcslee): implement
return ANONYMOUS_STRUCT;
}
- public void readStructEnd() {}
+ @Override
+ public void readStructEnd() throws TException {}
+ @Override
public TField readFieldBegin() throws TException {
// TODO(mcslee): implement
return ANONYMOUS_FIELD;
}
- public void readFieldEnd() {}
+ @Override
+ public void readFieldEnd() throws TException {}
+ @Override
public TMap readMapBegin() throws TException {
// TODO(mcslee): implement
return EMPTY_MAP;
}
- public void readMapEnd() {}
+ @Override
+ public void readMapEnd() throws TException {}
+ @Override
public TList readListBegin() throws TException {
// TODO(mcslee): implement
return EMPTY_LIST;
}
- public void readListEnd() {}
+ @Override
+ public void readListEnd() throws TException {}
+ @Override
public TSet readSetBegin() throws TException {
// TODO(mcslee): implement
return EMPTY_SET;
}
- public void readSetEnd() {}
+ @Override
+ public void readSetEnd() throws TException {}
+ @Override
public boolean readBool() throws TException {
return (readByte() == 1);
}
+ @Override
public byte readByte() throws TException {
// TODO(mcslee): implement
return 0;
}
+ @Override
public short readI16() throws TException {
// TODO(mcslee): implement
return 0;
}
+ @Override
public int readI32() throws TException {
// TODO(mcslee): implement
return 0;
}
+ @Override
public long readI64() throws TException {
// TODO(mcslee): implement
return 0;
}
+ @Override
public double readDouble() throws TException {
// TODO(mcslee): implement
return 0;
}
+ @Override
public String readString() throws TException {
// TODO(mcslee): implement
return "";
@@ -435,6 +469,7 @@
return "";
}
+ @Override
public ByteBuffer readBinary() throws TException {
// TODO(mcslee): implement
return ByteBuffer.wrap(new byte[0]);
diff --git a/lib/java/src/org/apache/thrift/server/AbstractNonblockingServer.java b/lib/java/src/org/apache/thrift/server/AbstractNonblockingServer.java
index 5c62b99..8c206e4 100644
--- a/lib/java/src/org/apache/thrift/server/AbstractNonblockingServer.java
+++ b/lib/java/src/org/apache/thrift/server/AbstractNonblockingServer.java
@@ -435,17 +435,23 @@
* has come in.
*/
public void changeSelectInterests() {
- if (state_ == FrameBufferState.AWAITING_REGISTER_WRITE) {
+ switch (state_) {
+ case AWAITING_REGISTER_WRITE:
// set the OP_WRITE interest
selectionKey_.interestOps(SelectionKey.OP_WRITE);
state_ = FrameBufferState.WRITING;
- } else if (state_ == FrameBufferState.AWAITING_REGISTER_READ) {
+ break;
+ case AWAITING_REGISTER_READ:
prepareRead();
- } else if (state_ == FrameBufferState.AWAITING_CLOSE) {
+ break;
+ case AWAITING_CLOSE:
close();
selectionKey_.cancel();
- } else {
- LOGGER.error("changeSelectInterest was called, but state is invalid (" + state_ + ")");
+ break;
+ default:
+ LOGGER.error(
+ "changeSelectInterest was called, but state is invalid ({})",
+ state_);
}
}
diff --git a/lib/java/src/org/apache/thrift/server/TNonblockingServer.java b/lib/java/src/org/apache/thrift/server/TNonblockingServer.java
index fe0365a..2358c63 100644
--- a/lib/java/src/org/apache/thrift/server/TNonblockingServer.java
+++ b/lib/java/src/org/apache/thrift/server/TNonblockingServer.java
@@ -239,7 +239,6 @@
} catch (TTransportException tte) {
// something went wrong accepting.
LOGGER.warn("Exception trying to accept!", tte);
- tte.printStackTrace();
if (clientKey != null) cleanupSelectionKey(clientKey);
if (client != null) client.close();
}
diff --git a/lib/java/src/org/apache/thrift/server/TServer.java b/lib/java/src/org/apache/thrift/server/TServer.java
index 80f4f86..bac06b2 100644
--- a/lib/java/src/org/apache/thrift/server/TServer.java
+++ b/lib/java/src/org/apache/thrift/server/TServer.java
@@ -123,7 +123,7 @@
*/
protected TProtocolFactory outputProtocolFactory_;
- private boolean isServing;
+ private volatile boolean isServing;
protected TServerEventHandler eventHandler_;
diff --git a/lib/java/src/org/apache/thrift/server/TSimpleServer.java b/lib/java/src/org/apache/thrift/server/TSimpleServer.java
index e815b2c..13501ef 100644
--- a/lib/java/src/org/apache/thrift/server/TSimpleServer.java
+++ b/lib/java/src/org/apache/thrift/server/TSimpleServer.java
@@ -77,9 +77,7 @@
if (eventHandler_ != null) {
eventHandler_.processContext(connectionContext, inputTransport, outputTransport);
}
- if(!processor.process(inputProtocol, outputProtocol)) {
- break;
- }
+ processor.process(inputProtocol, outputProtocol);
}
}
} catch (TTransportException ttx) {
diff --git a/lib/java/src/org/apache/thrift/server/TThreadPoolServer.java b/lib/java/src/org/apache/thrift/server/TThreadPoolServer.java
index 3b5f21e..db1ecb9 100644
--- a/lib/java/src/org/apache/thrift/server/TThreadPoolServer.java
+++ b/lib/java/src/org/apache/thrift/server/TThreadPoolServer.java
@@ -307,9 +307,10 @@
eventHandler.processContext(connectionContext, inputTransport, outputTransport);
}
- if(stopped_ || !processor.process(inputProtocol, outputProtocol)) {
+ if (stopped_) {
break;
}
+ processor.process(inputProtocol, outputProtocol);
}
} catch (TException tx) {
LOGGER.error("Thrift error occurred during processing of message.", tx);
@@ -320,11 +321,9 @@
// Ignore err-logging all transport-level/type exceptions
if ((realCause != null && realCause instanceof TTransportException)
|| (x instanceof TTransportException)) {
- if (LOGGER.isDebugEnabled()) {
- // Write to debug, just in case the exception gets required
- LOGGER
- .debug("Received TTransportException during processing of message, ignoring: ", x);
- }
+ LOGGER.debug(
+ "Received TTransportException during processing of message. Ignoring.",
+ x);
} else {
// Log the exception at error level and continue
LOGGER.error("Error occurred during processing of message.", x);
diff --git a/lib/java/src/org/apache/thrift/transport/AutoExpandingBuffer.java b/lib/java/src/org/apache/thrift/transport/AutoExpandingBuffer.java
index b02905f..fc3aa92 100644
--- a/lib/java/src/org/apache/thrift/transport/AutoExpandingBuffer.java
+++ b/lib/java/src/org/apache/thrift/transport/AutoExpandingBuffer.java
@@ -18,6 +18,8 @@
*/
package org.apache.thrift.transport;
+import java.util.Arrays;
+
/**
* Helper class that wraps a byte[] so that it can expand and be reused. Users
* should call resizeIfNecessary to make sure the buffer has suitable capacity,
@@ -25,28 +27,24 @@
* rate slightly faster than the requested capacity with the (untested)
* objective of avoiding expensive buffer allocations and copies.
*/
-public class AutoExpandingBuffer {
+class AutoExpandingBuffer {
private byte[] array;
- private final double growthCoefficient;
-
- public AutoExpandingBuffer(int initialCapacity, double growthCoefficient) {
- if (growthCoefficient < 1.0) {
- throw new IllegalArgumentException("Growth coefficient must be >= 1.0");
- }
- array = new byte[initialCapacity];
- this.growthCoefficient = growthCoefficient;
+ public AutoExpandingBuffer(int initialCapacity) {
+ this.array = new byte[initialCapacity];
}
public void resizeIfNecessary(int size) {
- if (array.length < size) {
- byte[] newBuf = new byte[(int)(size * growthCoefficient)];
- System.arraycopy(array, 0, newBuf, 0, array.length);
- array = newBuf;
+ final int currentCapacity = this.array.length;
+ if (currentCapacity < size) {
+ // Increase by a factor of 1.5x
+ int growCapacity = currentCapacity + (currentCapacity >> 1);
+ int newCapacity = Math.max(growCapacity, size);
+ this.array = Arrays.copyOf(array, newCapacity);
}
}
public byte[] array() {
- return array;
+ return this.array;
}
}
diff --git a/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java b/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java
index 081bc48..a28d254 100644
--- a/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java
@@ -28,8 +28,8 @@
private int pos = 0;
private int limit = 0;
- public AutoExpandingBufferReadTransport(int initialCapacity, double overgrowthCoefficient) {
- this.buf = new AutoExpandingBuffer(initialCapacity, overgrowthCoefficient);
+ public AutoExpandingBufferReadTransport(int initialCapacity) {
+ this.buf = new AutoExpandingBuffer(initialCapacity);
}
public void fill(TTransport inTrans, int length) throws TTransportException {
diff --git a/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferWriteTransport.java b/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferWriteTransport.java
index 9b35693..ec7e7d4 100644
--- a/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferWriteTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferWriteTransport.java
@@ -25,10 +25,29 @@
private final AutoExpandingBuffer buf;
private int pos;
+ private int res;
- public AutoExpandingBufferWriteTransport(int initialCapacity, double growthCoefficient) {
- this.buf = new AutoExpandingBuffer(initialCapacity, growthCoefficient);
- this.pos = 0;
+ /**
+ * Constructor.
+ * @param initialCapacity the initial capacity of the buffer
+ * @param frontReserve space, if any, to reserve at the beginning such
+ * that the first write is after this reserve.
+ * This allows framed transport to reserve space
+ * for the frame buffer length.
+ * @throws IllegalArgumentException if initialCapacity is less than one
+ * @throws IllegalArgumentException if frontReserve is less than zero
+ * @throws IllegalArgumentException if frontReserve is greater than initialCapacity
+ */
+ public AutoExpandingBufferWriteTransport(int initialCapacity, int frontReserve) {
+ if (initialCapacity < 1) {
+ throw new IllegalArgumentException("initialCapacity");
+ }
+ if (frontReserve < 0 || initialCapacity < frontReserve) {
+ throw new IllegalArgumentException("frontReserve");
+ }
+ this.buf = new AutoExpandingBuffer(initialCapacity);
+ this.pos = frontReserve;
+ this.res = frontReserve;
}
@Override
@@ -56,11 +75,14 @@
return buf;
}
- public int getPos() {
+ /**
+ * @return length of the buffer, including any front reserve
+ */
+ public int getLength() {
return pos;
}
public void reset() {
- pos = 0;
+ pos = res;
}
}
diff --git a/lib/java/src/org/apache/thrift/transport/TFastFramedTransport.java b/lib/java/src/org/apache/thrift/transport/TFastFramedTransport.java
index d265600..a1fd249 100644
--- a/lib/java/src/org/apache/thrift/transport/TFastFramedTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TFastFramedTransport.java
@@ -106,8 +106,8 @@
this.underlying = underlying;
this.maxLength = maxLength;
this.initialBufferCapacity = initialBufferCapacity;
- writeBuffer = new AutoExpandingBufferWriteTransport(initialBufferCapacity, 1.5);
- readBuffer = new AutoExpandingBufferReadTransport(initialBufferCapacity, 1.5);
+ readBuffer = new AutoExpandingBufferReadTransport(initialBufferCapacity);
+ writeBuffer = new AutoExpandingBufferWriteTransport(initialBufferCapacity, 4);
}
@Override
@@ -166,16 +166,19 @@
readBuffer.consumeBuffer(len);
}
+ /**
+ * Only clears the read buffer!
+ */
public void clear() {
- readBuffer = new AutoExpandingBufferReadTransport(initialBufferCapacity, 1.5);
+ readBuffer = new AutoExpandingBufferReadTransport(initialBufferCapacity);
}
@Override
public void flush() throws TTransportException {
- int length = writeBuffer.getPos();
- TFramedTransport.encodeFrameSize(length, i32buf);
- underlying.write(i32buf, 0, 4);
- underlying.write(writeBuffer.getBuf().array(), 0, length);
+ int payloadLength = writeBuffer.getLength() - 4;
+ byte[] data = writeBuffer.getBuf().array();
+ TFramedTransport.encodeFrameSize(payloadLength, data);
+ underlying.write(data, 0, payloadLength + 4);
writeBuffer.reset();
underlying.flush();
}
diff --git a/lib/java/src/org/apache/thrift/transport/TFramedTransport.java b/lib/java/src/org/apache/thrift/transport/TFramedTransport.java
index fa531ef..a006c3a 100644
--- a/lib/java/src/org/apache/thrift/transport/TFramedTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TFramedTransport.java
@@ -66,16 +66,25 @@
}
/**
+ * Something to fill in the first four bytes of the buffer
+ * to make room for the frame size. This allows the
+ * implementation to write once instead of twice.
+ */
+ private static final byte[] sizeFiller_ = new byte[] { 0x00, 0x00, 0x00, 0x00 };
+
+ /**
* Constructor wraps around another transport
*/
public TFramedTransport(TTransport transport, int maxLength) {
transport_ = transport;
maxLength_ = maxLength;
+ writeBuffer_.write(sizeFiller_, 0, 4);
}
public TFramedTransport(TTransport transport) {
transport_ = transport;
maxLength_ = TFramedTransport.DEFAULT_MAX_LENGTH;
+ writeBuffer_.write(sizeFiller_, 0, 4);
}
public void open() throws TTransportException {
@@ -155,12 +164,12 @@
@Override
public void flush() throws TTransportException {
byte[] buf = writeBuffer_.get();
- int len = writeBuffer_.len();
+ int len = writeBuffer_.len() - 4; // account for the prepended frame size
writeBuffer_.reset();
+ writeBuffer_.write(sizeFiller_, 0, 4); // make room for the next frame's size data
- encodeFrameSize(len, i32buf);
- transport_.write(i32buf, 0, 4);
- transport_.write(buf, 0, len);
+ encodeFrameSize(len, buf); // this is the frame length without the filler
+ transport_.write(buf, 0, len + 4); // we have to write the frame size and frame data
transport_.flush();
}
diff --git a/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java b/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java
index ef5f5c2..b19ac86 100644
--- a/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java
+++ b/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java
@@ -20,7 +20,7 @@
package org.apache.thrift.transport;
import org.apache.thrift.TByteArrayOutputStream;
-import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
/**
* Memory buffer-based implementation of the TTransport interface.
@@ -30,6 +30,8 @@
* Create a TMemoryBuffer with an initial buffer size of <i>size</i>. The
* internal buffer will grow as necessary to accommodate the size of the data
* being written to it.
+ *
+ * @param size the initial size of the buffer
*/
public TMemoryBuffer(int size) {
arr_ = new TByteArrayOutputStream(size);
@@ -69,11 +71,11 @@
/**
* Output the contents of the memory buffer as a String, using the supplied
* encoding
- * @param enc the encoding to use
+ * @param charset the encoding to use
* @return the contents of the memory buffer as a String
*/
- public String toString(String enc) throws UnsupportedEncodingException {
- return arr_.toString(enc);
+ public String toString(Charset charset) {
+ return arr_.toString(charset);
}
public String inspect() {
diff --git a/lib/java/src/org/apache/thrift/transport/TNonblockingServerSocket.java b/lib/java/src/org/apache/thrift/transport/TNonblockingServerSocket.java
index ef82ac2..df37cb0 100644
--- a/lib/java/src/org/apache/thrift/transport/TNonblockingServerSocket.java
+++ b/lib/java/src/org/apache/thrift/transport/TNonblockingServerSocket.java
@@ -103,7 +103,7 @@
try {
serverSocket_.setSoTimeout(0);
} catch (SocketException sx) {
- sx.printStackTrace();
+ LOGGER.error("Socket exception while setting socket timeout", sx);
}
}
}
diff --git a/lib/java/src/org/apache/thrift/transport/TSSLTransportFactory.java b/lib/java/src/org/apache/thrift/transport/TSSLTransportFactory.java
index 2232a31..73dfaaf 100644
--- a/lib/java/src/org/apache/thrift/transport/TSSLTransportFactory.java
+++ b/lib/java/src/org/apache/thrift/transport/TSSLTransportFactory.java
@@ -37,11 +37,17 @@
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* A Factory for providing and setting up Client and Server SSL wrapped
* TSocket and TServerSocket
*/
public class TSSLTransportFactory {
+
+ private static final Logger LOGGER =
+ LoggerFactory.getLogger(TSSLTransportFactory.class);
/**
* Get a SSL wrapped TServerSocket bound to the specified port. In this
@@ -225,14 +231,14 @@
try {
in.close();
} catch (IOException e) {
- e.printStackTrace();
+ LOGGER.warn("Unable to close stream", e);
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
- e.printStackTrace();
+ LOGGER.warn("Unable to close stream", e);
}
}
}
diff --git a/lib/java/src/org/apache/thrift/transport/TSaslClientTransport.java b/lib/java/src/org/apache/thrift/transport/TSaslClientTransport.java
index 8122289..4b1ca0a 100644
--- a/lib/java/src/org/apache/thrift/transport/TSaslClientTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TSaslClientTransport.java
@@ -19,7 +19,7 @@
package org.apache.thrift.transport;
-import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import java.util.Map;
import javax.security.auth.callback.CallbackHandler;
@@ -97,12 +97,7 @@
LOGGER.debug("Sending mechanism name {} and initial response of length {}", mechanism,
initialResponse.length);
- byte[] mechanismBytes;
- try {
- mechanismBytes = mechanism.getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new TTransportException(e);
- }
+ byte[] mechanismBytes = mechanism.getBytes(StandardCharsets.UTF_8);
sendSaslMessage(NegotiationStatus.START,
mechanismBytes);
// Send initial response
diff --git a/lib/java/src/org/apache/thrift/transport/TSaslServerTransport.java b/lib/java/src/org/apache/thrift/transport/TSaslServerTransport.java
index e6c0e3e..39b81ca 100644
--- a/lib/java/src/org/apache/thrift/transport/TSaslServerTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TSaslServerTransport.java
@@ -19,8 +19,8 @@
package org.apache.thrift.transport;
-import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
+import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -31,7 +31,6 @@
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
-import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -132,12 +131,7 @@
}
// Get the mechanism name.
- String mechanismName;
- try {
- mechanismName = new String(message.payload, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new TTransportException("JVM DOES NOT SUPPORT UTF-8");
- }
+ String mechanismName = new String(message.payload, StandardCharsets.UTF_8);
TSaslServerDefinition serverDefinition = serverDefinitionMap.get(mechanismName);
LOGGER.debug("Received mechanism name '{}'", mechanismName);
diff --git a/lib/java/src/org/apache/thrift/transport/TSaslTransport.java b/lib/java/src/org/apache/thrift/transport/TSaslTransport.java
index bbd3f9a..c858425 100644
--- a/lib/java/src/org/apache/thrift/transport/TSaslTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TSaslTransport.java
@@ -19,7 +19,7 @@
package org.apache.thrift.transport;
-import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@@ -158,9 +158,9 @@
messageHeader[0] = status.getValue();
EncodingUtils.encodeBigEndian(payload.length, messageHeader, STATUS_BYTES);
- if (LOGGER.isDebugEnabled())
- LOGGER.debug(getRole() + ": Writing message with status {} and payload length {}",
- status, payload.length);
+ LOGGER.debug("{}: Writing message with status {} and payload length {}",
+ getRole(), status, payload.length);
+
underlyingTransport.write(messageHeader);
underlyingTransport.write(payload);
underlyingTransport.flush();
@@ -194,17 +194,11 @@
underlyingTransport.readAll(payload, 0, payload.length);
if (status == NegotiationStatus.BAD || status == NegotiationStatus.ERROR) {
- try {
- String remoteMessage = new String(payload, "UTF-8");
- throw new TTransportException("Peer indicated failure: " + remoteMessage);
- } catch (UnsupportedEncodingException e) {
- throw new TTransportException(e);
- }
+ String remoteMessage = new String(payload, StandardCharsets.UTF_8);
+ throw new TTransportException("Peer indicated failure: " + remoteMessage);
}
-
- if (LOGGER.isDebugEnabled())
- LOGGER.debug(getRole() + ": Received message with status {} and payload length {}",
- status, payload.length);
+ LOGGER.debug("{}: Received message with status {} and payload length {}",
+ getRole(), status, payload.length);
return new SaslResponse(status, payload);
}
@@ -224,7 +218,7 @@
*/
protected TTransportException sendAndThrowMessage(NegotiationStatus status, String message) throws TTransportException {
try {
- sendSaslMessage(status, message.getBytes("UTF-8"));
+ sendSaslMessage(status, message.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
LOGGER.warn("Could not send failure response", e);
message += "\nAlso, could not send response: " + e.toString();
@@ -323,7 +317,7 @@
if (!readSaslHeader && e.getType() == TTransportException.END_OF_FILE) {
underlyingTransport.close();
LOGGER.debug("No data or no sasl data in the stream");
- throw new TSaslTransportException("No data or no sasl data in the stream");
+ throw new TSaslTransportException("No data or no sasl data in the stream during negotiation", e);
}
throw e;
}
diff --git a/lib/java/test/org/apache/thrift/Fixtures.java b/lib/java/test/org/apache/thrift/Fixtures.java
index 81671d8..61f40a5 100644
--- a/lib/java/test/org/apache/thrift/Fixtures.java
+++ b/lib/java/test/org/apache/thrift/Fixtures.java
@@ -20,6 +20,7 @@
package org.apache.thrift;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -267,7 +268,7 @@
oneOfEach.setInteger64((long) 6000 * 1000 * 1000);
oneOfEach.setDouble_precision(Math.PI);
oneOfEach.setSome_characters("JSON THIS! \"\1");
- oneOfEach.setZomg_unicode(new String(kUnicodeBytes, "UTF-8"));
+ oneOfEach.setZomg_unicode(new String(kUnicodeBytes, StandardCharsets.UTF_8));
oneOfEach.setBase64(ByteBuffer.wrap("base64".getBytes()));
// byte, i16, and i64 lists are populated by default constructor
diff --git a/lib/java/test/org/apache/thrift/TestMultiplexedProcessor.java b/lib/java/test/org/apache/thrift/TestMultiplexedProcessor.java
index 01776ca..85e7966 100644
--- a/lib/java/test/org/apache/thrift/TestMultiplexedProcessor.java
+++ b/lib/java/test/org/apache/thrift/TestMultiplexedProcessor.java
@@ -57,13 +57,12 @@
static class StubProcessor implements TProcessor {
@Override
- public boolean process(TProtocol in, TProtocol out) throws TException {
+ public void process(TProtocol in, TProtocol out) throws TException {
TMessage msg = in.readMessageBegin();
if (!"func".equals(msg.name) || msg.type!=TMessageType.CALL || msg.seqid!=42) {
throw new TException("incorrect parameters");
}
out.writeMessageBegin(new TMessage("func", TMessageType.REPLY, 42));
- return true;
}
}
diff --git a/lib/java/test/org/apache/thrift/TestShortStack.java b/lib/java/test/org/apache/thrift/TestShortStack.java
deleted file mode 100644
index 07831e5..0000000
--- a/lib/java/test/org/apache/thrift/TestShortStack.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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.
- */
-package org.apache.thrift;
-
-import java.util.Stack;
-
-import junit.framework.TestCase;
-
-public class TestShortStack extends TestCase {
- private static final int NUM_TRIALS = 5;
- private static final int NUM_REPS = 10000000;
-
- public void testOps() throws Exception {
- ShortStack s = new ShortStack(10);
- s.push((short)10);
- s.push((short)11);
- s.push((short)12);
- assertEquals((short)12, s.peek());
- assertEquals((short)12, s.peek());
- assertEquals((short)12, s.pop());
- assertEquals((short)11, s.pop());
- s.push((short)40);
- assertEquals((short)40, s.peek());
- assertEquals((short)40, s.pop());
- assertEquals((short)10, s.peek());
- assertEquals((short)10, s.pop());
- try {
- s.peek();
- fail("should have thrown an exception!");
- } catch (Exception e) {
- // yay
- }
-
- try {
- s.pop();
- fail("should have thrown an exception!");
- } catch (Exception e) {
- // yay
- }
- }
-
- public void testGrow() throws Exception {
- ShortStack s = new ShortStack(1);
- s.push((short)1);
- s.push((short)1);
- s.push((short)1);
- s.push((short)1);
- s.push((short)1);
- }
-
- public static void main(String[] args) throws Exception {
- for (int trial = 0; trial < NUM_TRIALS; trial++) {
- long start = System.currentTimeMillis();
- ShortStack s = new ShortStack(10);
- for (int rep = 0; rep < NUM_REPS; rep++) {
- s.push((short)1);
- s.push((short)11);
- s.push((short)111);
- s.pop();
- s.pop();
- s.push((short)12);
- s.push((short)121);
- s.push((short)1211);
- s.push((short)12111);
- s.pop();
- s.pop();
- s.pop();
- s.pop();
- s.push((short)5);
- s.pop();
- s.pop();
- }
- long end = System.currentTimeMillis();
- System.out.println("ShortStack: " + (end-start));
-
- start = System.currentTimeMillis();
- Stack<Short> stdStack = new Stack<Short>();
- for (int rep = 0; rep < NUM_REPS; rep++) {
- stdStack.push((short)1);
- stdStack.push((short)11);
- stdStack.push((short)111);
- stdStack.pop();
- stdStack.pop();
- stdStack.push((short)12);
- stdStack.push((short)121);
- stdStack.push((short)1211);
- stdStack.push((short)12111);
- stdStack.pop();
- stdStack.pop();
- stdStack.pop();
- stdStack.pop();
- stdStack.push((short)5);
- stdStack.pop();
- stdStack.pop();
- }
- end = System.currentTimeMillis();
- System.out.println("Built-in stack: " + (end-start));
- }
- }
-}
diff --git a/lib/java/test/org/apache/thrift/protocol/TestShortStack.java b/lib/java/test/org/apache/thrift/protocol/TestShortStack.java
new file mode 100644
index 0000000..c8e78ee
--- /dev/null
+++ b/lib/java/test/org/apache/thrift/protocol/TestShortStack.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+package org.apache.thrift.protocol;
+
+import junit.framework.TestCase;
+
+public class TestShortStack extends TestCase {
+
+ public void testOps() throws Exception {
+ ShortStack s = new ShortStack(1);
+ s.push((short)10);
+ s.push((short)11);
+ s.push((short)12);
+ assertEquals((short)12, s.pop());
+ assertEquals((short)11, s.pop());
+ s.push((short)40);
+ assertEquals((short)40, s.pop());
+ assertEquals((short)10, s.pop());
+ try {
+ s.pop();
+ fail("should have thrown an exception!");
+ } catch (Exception e) {
+ // yay
+ }
+ }
+}
diff --git a/lib/java/test/org/apache/thrift/protocol/TestTField.java b/lib/java/test/org/apache/thrift/protocol/TestTField.java
new file mode 100644
index 0000000..f72c259
--- /dev/null
+++ b/lib/java/test/org/apache/thrift/protocol/TestTField.java
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+package org.apache.thrift.protocol;
+
+import junit.framework.TestCase;
+import static org.junit.Assert.assertNotEquals;
+
+public abstract class TestTField extends TestCase {
+
+ public void testConstructor() {
+ TField uut = new TField();
+ assertEquals("", uut.name);
+ assertEquals(TType.STOP, uut.type);
+ assertEquals(0, uut.id);
+
+ uut = new TField("foo", TType.VOID, (short)42);
+ assertEquals("foo", uut.name);
+ assertEquals(TType.VOID, uut.type);
+ assertEquals(42, uut.id);
+ }
+
+ public void testEquality() {
+ TField uut1 = new TField();
+ TField uut2 = new TField();
+ assertEquals(uut1, uut2);
+ assertEquals(uut1.hashCode(), uut2.hashCode());
+
+ uut1 = new TField("foo", TType.I32, (short)1);
+ uut2 = new TField("foo", TType.I32, (short)2);
+ assertNotEquals(uut1, uut2);
+ assertNotEquals(uut1.hashCode(), uut2.hashCode());
+
+ uut1 = new TField("foo", TType.VOID, (short)1);
+ uut2 = new TField("foo", TType.I32, (short)1);
+ assertNotEquals(uut1, uut2);
+ assertNotEquals(uut1.hashCode(), uut2.hashCode());
+
+ uut1 = new TField("foo", TType.VOID, (short)5);
+ uut2 = new TField("bar", TType.I32, (short)5);
+ assertEquals(uut1, uut2); // name field is ignored
+ assertEquals(uut1.hashCode(), uut2.hashCode());
+ }
+
+}
diff --git a/lib/java/test/org/apache/thrift/protocol/TestTJSONProtocol.java b/lib/java/test/org/apache/thrift/protocol/TestTJSONProtocol.java
index 1320749..c2ca1fa 100644
--- a/lib/java/test/org/apache/thrift/protocol/TestTJSONProtocol.java
+++ b/lib/java/test/org/apache/thrift/protocol/TestTJSONProtocol.java
@@ -18,7 +18,7 @@
*/
package org.apache.thrift.protocol;
-import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TJSONProtocol;
@@ -35,13 +35,13 @@
return false;
}
- public void testEscapedUnicode() throws TException, IOException {
+ public void testEscapedUnicode() throws TException {
String jsonString = "\"hello unicode \\u0e01\\ud834\\udd1e world\"";
String expectedString = "hello unicode \u0e01\ud834\udd1e world";
TMemoryBuffer buffer = new TMemoryBuffer(1000);
TJSONProtocol protocol = new TJSONProtocol(buffer);
- buffer.write(jsonString.getBytes("UTF-8"));
+ buffer.write(jsonString.getBytes(StandardCharsets.UTF_8));
assertEquals(expectedString, protocol.readString());
}
diff --git a/lib/java/test/org/apache/thrift/protocol/TestTSimpleJSONProtocol.java b/lib/java/test/org/apache/thrift/protocol/TestTSimpleJSONProtocol.java
index b8c4657..9d125b1 100644
--- a/lib/java/test/org/apache/thrift/protocol/TestTSimpleJSONProtocol.java
+++ b/lib/java/test/org/apache/thrift/protocol/TestTSimpleJSONProtocol.java
@@ -18,7 +18,7 @@
*/
package org.apache.thrift.protocol;
-import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import junit.framework.TestCase;
@@ -40,11 +40,7 @@
}
private String bufToString() {
- try {
- return buf.toString("UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
+ return buf.toString(StandardCharsets.UTF_8);
}
public void testHolyMoley() throws TException {
diff --git a/lib/java/test/org/apache/thrift/test/TestClient.java b/lib/java/test/org/apache/thrift/test/TestClient.java
index feaa972..84410ce 100644
--- a/lib/java/test/org/apache/thrift/test/TestClient.java
+++ b/lib/java/test/org/apache/thrift/test/TestClient.java
@@ -752,13 +752,18 @@
testClient.testOneway(3);
long onewayElapsedMillis = (System.nanoTime() - startOneway) / 1000000;
if (onewayElapsedMillis > 200) {
- System.out.println("Oneway test failed: took " +
+ System.out.println("Oneway test took too long to execute failed: took " +
Long.toString(onewayElapsedMillis) +
"ms");
- System.out.printf("*** FAILURE ***\n");
+ System.out.println("oneway calls are 'fire and forget' and therefore should not cause blocking.");
+ System.out.println("Some transports (HTTP) have a required response, and typically this failure");
+ System.out.println("means the transport response was delayed until after the execution");
+ System.out.println("of the RPC. The server should post the transport response immediately and");
+ System.out.println("before executing the RPC.");
+ System.out.println("*** FAILURE ***");
returnCode |= ERR_BASETYPES;
} else {
- System.out.println("Success - took " +
+ System.out.println("Success - fire and forget only took " +
Long.toString(onewayElapsedMillis) +
"ms");
}
diff --git a/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBuffer.java b/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBuffer.java
index 337dcf8..c353489 100644
--- a/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBuffer.java
+++ b/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBuffer.java
@@ -23,7 +23,7 @@
public class TestAutoExpandingBuffer extends TestCase {
public void testExpands() throws Exception {
// has expected initial capacity
- AutoExpandingBuffer b = new AutoExpandingBuffer(10, 1.5);
+ AutoExpandingBuffer b = new AutoExpandingBuffer(10);
assertEquals(10, b.array().length);
// doesn't shrink
diff --git a/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferReadTransport.java b/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferReadTransport.java
index 2e1f947..83ebc2d 100644
--- a/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferReadTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferReadTransport.java
@@ -32,7 +32,7 @@
}
public void testIt() throws Exception {
- AutoExpandingBufferReadTransport t = new AutoExpandingBufferReadTransport(150, 1.5);
+ AutoExpandingBufferReadTransport t = new AutoExpandingBufferReadTransport(150);
TMemoryInputTransport membuf = new TMemoryInputTransport(HUNDRED_BYTES);
diff --git a/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferWriteTransport.java b/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferWriteTransport.java
index d5f239d..86b5b0d 100644
--- a/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferWriteTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferWriteTransport.java
@@ -19,26 +19,51 @@
package org.apache.thrift.transport;
import java.nio.ByteBuffer;
+import org.junit.Test;
+import static org.junit.Assert.*;
-import junit.framework.TestCase;
+public class TestAutoExpandingBufferWriteTransport {
-public class TestAutoExpandingBufferWriteTransport extends TestCase {
-
+ @Test
public void testIt() throws Exception {
- AutoExpandingBufferWriteTransport t = new AutoExpandingBufferWriteTransport(1, 1.5);
+ AutoExpandingBufferWriteTransport t = new AutoExpandingBufferWriteTransport(1, 0);
+ assertEquals(0, t.getLength());
assertEquals(1, t.getBuf().array().length);
byte[] b1 = new byte[]{1,2,3};
t.write(b1);
- assertEquals(3, t.getPos());
+ assertEquals(3, t.getLength());
assertTrue(t.getBuf().array().length >= 3);
assertEquals(ByteBuffer.wrap(b1), ByteBuffer.wrap(t.getBuf().array(), 0, 3));
t.reset();
+ assertEquals(0, t.getLength());
assertTrue(t.getBuf().array().length >= 3);
- assertEquals(0, t.getPos());
byte[] b2 = new byte[]{4,5};
t.write(b2);
- assertEquals(2, t.getPos());
+ assertEquals(2, t.getLength());
assertEquals(ByteBuffer.wrap(b2), ByteBuffer.wrap(t.getBuf().array(), 0, 2));
+
+ AutoExpandingBufferWriteTransport uut = new AutoExpandingBufferWriteTransport(8, 4);
+ assertEquals(4, uut.getLength());
+ assertEquals(8, uut.getBuf().array().length);
+ uut.write(b1);
+ assertEquals(7, uut.getLength());
+ assertEquals(8, uut.getBuf().array().length);
+ assertEquals(ByteBuffer.wrap(b1), ByteBuffer.wrap(uut.getBuf().array(), 4, 3));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBadInitialSize() throws IllegalArgumentException {
+ new AutoExpandingBufferWriteTransport(0, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBadFrontReserveSize() throws IllegalArgumentException {
+ new AutoExpandingBufferWriteTransport(4, -1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testTooSmallFrontReserveSize() throws IllegalArgumentException {
+ new AutoExpandingBufferWriteTransport(4, 5);
}
}
diff --git a/lib/java/test/org/apache/thrift/transport/TestTFramedTransport.java b/lib/java/test/org/apache/thrift/transport/TestTFramedTransport.java
index 7e889d6..e30d74b 100644
--- a/lib/java/test/org/apache/thrift/transport/TestTFramedTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/TestTFramedTransport.java
@@ -125,11 +125,11 @@
assertEquals(0, countingTrans.writeCount);
trans.flush();
- assertEquals(2, countingTrans.writeCount);
+ assertEquals(1, countingTrans.writeCount);
trans.write(byteSequence(0, 245));
trans.flush();
- assertEquals(4, countingTrans.writeCount);
+ assertEquals(2, countingTrans.writeCount);
DataInputStream din = new DataInputStream(new ByteArrayInputStream(baos.toByteArray()));
assertEquals(256, din.readInt());
diff --git a/lib/java/test/org/apache/thrift/transport/TestTSaslTransports.java b/lib/java/test/org/apache/thrift/transport/TestTSaslTransports.java
index 788395f..36a06e9 100644
--- a/lib/java/test/org/apache/thrift/transport/TestTSaslTransports.java
+++ b/lib/java/test/org/apache/thrift/transport/TestTSaslTransports.java
@@ -20,6 +20,7 @@
package org.apache.thrift.transport;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@@ -332,12 +333,8 @@
throw new SaslException("Already complete!");
}
- try {
- hasProvidedInitialResponse = true;
- return username.getBytes("UTF-8");
- } catch (IOException e) {
- throw new SaslException(e.toString());
- }
+ hasProvidedInitialResponse = true;
+ return username.getBytes(StandardCharsets.UTF_8);
}
public boolean isComplete() { return hasProvidedInitialResponse; }
public byte[] unwrap(byte[] incoming, int offset, int len) {
@@ -354,11 +351,7 @@
private String user;
public String getMechanismName() { return "ANONYMOUS"; }
public byte[] evaluateResponse(byte[] response) throws SaslException {
- try {
- this.user = new String(response, "UTF-8");
- } catch (IOException e) {
- throw new SaslException(e.toString());
- }
+ this.user = new String(response, StandardCharsets.UTF_8);
return null;
}
public boolean isComplete() { return user != null; }
diff --git a/lib/js/Gruntfile.js b/lib/js/Gruntfile.js
index bb7691a..87b826f 100644
--- a/lib/js/Gruntfile.js
+++ b/lib/js/Gruntfile.js
@@ -68,6 +68,16 @@
ThriftGenDeepConstructor: {
command: '../../compiler/cpp/thrift -gen js -o test ../../test/JsDeepConstructorTest.thrift'
},
+ ThriftBrowserifyNodeInt64: {
+ command: [
+ './node_modules/browserify/bin/cmd.js ./node_modules/node-int64/Int64.js -s Int64 -o test/build/js/lib/Int64.js',
+ './node_modules/browserify/bin/cmd.js ../nodejs/lib/thrift/int64_util.js -s Int64Util -o test/build/js/lib/Int64Util.js',
+ './node_modules/browserify/bin/cmd.js ./node_modules/json-int64/index.js -s JSONInt64 -o test/build/js/lib/JSONInt64.js'
+ ].join(' && ')
+ },
+ ThriftGenInt64: {
+ command: '../../compiler/cpp/thrift -gen js -o test ../../test/Int64Test.thrift'
+ },
ThriftGenDoubleConstants: {
command: '../../compiler/cpp/thrift -gen js -o test ../../test/DoubleConstantsTest.thrift'
},
@@ -147,6 +157,18 @@
},
}
},
+ ThriftJS_Int64: {
+ options: {
+ urls: [
+ 'http://localhost:8089/test-int64.html'
+ ],
+ puppeteer: {
+ headless: true,
+ args: ['--no-sandbox'],
+ ignoreHTTPSErrors: true,
+ },
+ }
+ },
ThriftWS: {
options: {
urls: [
@@ -218,7 +240,7 @@
}
},
jshint: {
- // The main thrift library file. not es6 yet :(
+ // The main Thrift library file. not es6 yet :(
lib: {
src: ['src/**/*.js'],
},
@@ -261,7 +283,7 @@
grunt.loadNpmTasks('grunt-jsdoc');
grunt.loadNpmTasks('grunt-shell-spawn');
- grunt.registerTask('wait', 'Wait just one second for server to start', function () {
+ grunt.registerTask('wait', 'Wait just one second for the server to start', function () {
var done = this.async();
setTimeout(function() {
done(true);
@@ -269,24 +291,37 @@
});
grunt.registerTask('installAndGenerate', [
- 'shell:InstallThriftJS', 'shell:InstallThriftNodeJSDep', 'shell:ThriftGen',
+ 'shell:InstallThriftJS',
+ 'shell:InstallThriftNodeJSDep',
+ 'shell:ThriftGen',
'shell:ThriftGenDeepConstructor',
+ 'shell:ThriftGenDoubleConstants',
'shell:InstallTestLibs',
+ 'shell:ThriftBrowserifyNodeInt64',
+ 'shell:ThriftGenInt64'
]);
grunt.registerTask('test', [
'installAndGenerate',
'jshint',
- 'shell:ThriftTestServer', 'shell:ThriftTestServer_TLS',
- 'shell:ThriftTestServerES6', 'shell:ThriftTestServerES6_TLS',
+ 'shell:ThriftTestServer',
+ 'shell:ThriftTestServer_TLS',
+ 'shell:ThriftTestServerES6',
+ 'shell:ThriftTestServerES6_TLS',
'wait',
'qunit:ThriftDeepConstructor',
- 'qunit:ThriftJS', 'qunit:ThriftJS_TLS',
+ 'qunit:ThriftJS',
+ 'qunit:ThriftJS_TLS',
+ 'qunit:ThriftJS_DoubleRendering',
'qunit:ThriftWS',
- 'qunit:ThriftJSJQ', 'qunit:ThriftJSJQ_TLS',
+ 'qunit:ThriftJSJQ',
+ 'qunit:ThriftJSJQ_TLS',
'qunit:ThriftWSES6',
- 'shell:ThriftTestServer:kill', 'shell:ThriftTestServer_TLS:kill',
- 'shell:ThriftTestServerES6:kill', 'shell:ThriftTestServerES6_TLS:kill',
+ 'qunit:ThriftJS_Int64',
+ 'shell:ThriftTestServer:kill',
+ 'shell:ThriftTestServer_TLS:kill',
+ 'shell:ThriftTestServerES6:kill',
+ 'shell:ThriftTestServerES6_TLS:kill',
]);
grunt.registerTask('default', ['test', 'concat', 'uglify', 'jsdoc']);
};
diff --git a/lib/js/Makefile.am b/lib/js/Makefile.am
index 9ea20a4..b534042 100644
--- a/lib/js/Makefile.am
+++ b/lib/js/Makefile.am
@@ -18,13 +18,45 @@
#
# Make sure this doesn't fail if ant is not configured.
-# We call install twice to work around npm issues
+# We call npm install twice to work around older npm issues
+# (note these issues may no longer be present, but it is ok)
#
+
if HAVE_NPM
+
SUBDIRS = test
-check-local: all
+prereq:
$(NPM) install || $(NPM) install
$(NPM) list
+
+check-local: prereq all
./node_modules/.bin/grunt
+
+doc: prereq
+ ./node_modules/.bin/grunt jsdoc
+
endif
+
+clean-local:
+ $(RM) -r dist
+ $(RM) -r doc
+ $(RM) -r node_modules
+ $(RM) -r test/build/
+ $(RM) -r test/gen-*/
+
+dist-hook:
+ $(RM) -r $(distdir)/dist/
+ $(RM) -r $(distdir)/doc/
+ $(RM) -r $(distdir)/node_modules/
+ $(RM) -r $(distdir)/test/build/
+ $(RM) -r $(distdir)/test/gen-*/
+
+EXTRA_DIST = \
+ coding_standards.md \
+ Gruntfile.js \
+ package.json \
+ package-lock.json \
+ README.md \
+ src \
+ test
diff --git a/lib/js/README.md b/lib/js/README.md
index 9d51e2a..5c7a1c2 100644
--- a/lib/js/README.md
+++ b/lib/js/README.md
@@ -138,3 +138,8 @@
thrift --gen js:ts file.thrift
+# Breaking Changes
+
+## 0.13.0
+
+1. 64-bit integer constants are now generatd using node-int64 e.g.: var x = new Int64("7fffffffffffffff");
diff --git a/lib/js/package-lock.json b/lib/js/package-lock.json
index 63d81c3..9110814 100644
--- a/lib/js/package-lock.json
+++ b/lib/js/package-lock.json
@@ -1,14 +1,54 @@
{
"name": "thrift",
- "version": "1.0.0",
+ "version": "0.13.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "JSONStream": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+ "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+ "dev": true,
+ "requires": {
+ "jsonparse": "^1.2.0",
+ "through": ">=2.2.7 <3"
+ }
+ },
"abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
},
+ "acorn": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz",
+ "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==",
+ "dev": true
+ },
+ "acorn-dynamic-import": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz",
+ "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==",
+ "dev": true
+ },
+ "acorn-node": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz",
+ "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==",
+ "dev": true,
+ "requires": {
+ "acorn": "^6.0.2",
+ "acorn-dynamic-import": "^4.0.0",
+ "acorn-walk": "^6.1.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "acorn-walk": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz",
+ "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==",
+ "dev": true
+ },
"agent-base": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
@@ -109,12 +149,30 @@
"integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
"dev": true
},
+ "array-filter": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
+ "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
+ "dev": true
+ },
"array-find-index": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
"integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
"dev": true
},
+ "array-map": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
+ "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=",
+ "dev": true
+ },
+ "array-reduce": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz",
+ "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=",
+ "dev": true
+ },
"array-slice": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
@@ -137,6 +195,43 @@
"safer-buffer": "~2.1.0"
}
},
+ "asn1.js": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "assert": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+ "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+ "dev": true,
+ "requires": {
+ "util": "0.10.3"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+ "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+ "dev": true
+ },
+ "util": {
+ "version": "0.10.3",
+ "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.1"
+ }
+ }
+ }
+ },
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
@@ -254,6 +349,12 @@
}
}
},
+ "base64-js": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
+ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
+ "dev": true
+ },
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
@@ -265,9 +366,15 @@
}
},
"bluebird": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz",
- "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg=="
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz",
+ "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw=="
+ },
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+ "dev": true
},
"brace-expansion": {
"version": "1.1.11",
@@ -308,6 +415,219 @@
}
}
},
+ "brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+ "dev": true
+ },
+ "browser-pack": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz",
+ "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "combine-source-map": "~0.8.0",
+ "defined": "^1.0.0",
+ "safe-buffer": "^5.1.1",
+ "through2": "^2.0.0",
+ "umd": "^3.0.0"
+ }
+ },
+ "browser-resolve": {
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz",
+ "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==",
+ "dev": true,
+ "requires": {
+ "resolve": "1.1.7"
+ }
+ },
+ "browserify": {
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz",
+ "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "assert": "^1.4.0",
+ "browser-pack": "^6.0.1",
+ "browser-resolve": "^1.11.0",
+ "browserify-zlib": "~0.2.0",
+ "buffer": "^5.0.2",
+ "cached-path-relative": "^1.0.0",
+ "concat-stream": "^1.6.0",
+ "console-browserify": "^1.1.0",
+ "constants-browserify": "~1.0.0",
+ "crypto-browserify": "^3.0.0",
+ "defined": "^1.0.0",
+ "deps-sort": "^2.0.0",
+ "domain-browser": "^1.2.0",
+ "duplexer2": "~0.1.2",
+ "events": "^2.0.0",
+ "glob": "^7.1.0",
+ "has": "^1.0.0",
+ "htmlescape": "^1.1.0",
+ "https-browserify": "^1.0.0",
+ "inherits": "~2.0.1",
+ "insert-module-globals": "^7.0.0",
+ "labeled-stream-splicer": "^2.0.0",
+ "mkdirp": "^0.5.0",
+ "module-deps": "^6.0.0",
+ "os-browserify": "~0.3.0",
+ "parents": "^1.0.1",
+ "path-browserify": "~0.0.0",
+ "process": "~0.11.0",
+ "punycode": "^1.3.2",
+ "querystring-es3": "~0.2.0",
+ "read-only-stream": "^2.0.0",
+ "readable-stream": "^2.0.2",
+ "resolve": "^1.1.4",
+ "shasum": "^1.0.0",
+ "shell-quote": "^1.6.1",
+ "stream-browserify": "^2.0.0",
+ "stream-http": "^2.0.0",
+ "string_decoder": "^1.1.1",
+ "subarg": "^1.0.0",
+ "syntax-error": "^1.1.1",
+ "through2": "^2.0.0",
+ "timers-browserify": "^1.0.1",
+ "tty-browserify": "0.0.1",
+ "url": "~0.11.0",
+ "util": "~0.10.1",
+ "vm-browserify": "^1.0.0",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "browserify-zlib": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+ "dev": true,
+ "requires": {
+ "pako": "~1.0.5"
+ }
+ },
+ "glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "pako": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz",
+ "integrity": "sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "string_decoder": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
+ "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "browserify-aes": {
+ "version": "1.2.0",
+ "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+ "dev": true,
+ "requires": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "browserify-cipher": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+ "dev": true,
+ "requires": {
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
+ }
+ },
+ "browserify-des": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+ "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "browserify-rsa": {
+ "version": "4.0.1",
+ "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "randombytes": "^2.0.1"
+ }
+ },
+ "browserify-sign": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
+ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.1",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.2",
+ "elliptic": "^6.0.0",
+ "inherits": "^2.0.1",
+ "parse-asn1": "^5.0.0"
+ }
+ },
"browserify-zlib": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
@@ -317,6 +637,16 @@
"pako": "~0.2.0"
}
},
+ "buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+ "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@@ -329,12 +659,24 @@
"integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=",
"dev": true
},
+ "buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+ "dev": true
+ },
"builtin-modules": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
"dev": true
},
+ "builtin-status-codes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+ "dev": true
+ },
"cache-base": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
@@ -352,6 +694,12 @@
"unset-value": "^1.0.0"
}
},
+ "cached-path-relative": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz",
+ "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==",
+ "dev": true
+ },
"camelcase": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
@@ -404,6 +752,16 @@
"supports-color": "^5.3.0"
}
},
+ "cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
"class-utils": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
@@ -508,6 +866,18 @@
"integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
"dev": true
},
+ "combine-source-map": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz",
+ "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=",
+ "dev": true,
+ "requires": {
+ "convert-source-map": "~1.1.0",
+ "inline-source-map": "~0.6.0",
+ "lodash.memoize": "~3.0.3",
+ "source-map": "~0.5.3"
+ }
+ },
"combined-stream": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
@@ -576,6 +946,18 @@
"date-now": "^0.1.4"
}
},
+ "constants-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.1.3",
+ "resolved": "http://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
+ "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=",
+ "dev": true
+ },
"copy-descriptor": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
@@ -588,6 +970,43 @@
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
},
+ "create-ecdh": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
+ "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.0.0"
+ }
+ },
+ "create-hash": {
+ "version": "1.2.0",
+ "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.7",
+ "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -601,6 +1020,25 @@
"which": "^1.2.9"
}
},
+ "crypto-browserify": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+ "dev": true,
+ "requires": {
+ "browserify-cipher": "^1.0.0",
+ "browserify-sign": "^4.0.0",
+ "create-ecdh": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.0",
+ "diffie-hellman": "^5.0.0",
+ "inherits": "^2.0.1",
+ "pbkdf2": "^3.0.3",
+ "public-encrypt": "^4.0.0",
+ "randombytes": "^2.0.0",
+ "randomfill": "^1.0.3"
+ }
+ },
"currently-unhandled": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
@@ -705,18 +1143,76 @@
}
}
},
+ "defined": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
+ "dev": true
+ },
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"dev": true
},
+ "deps-sort": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz",
+ "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "shasum": "^1.0.0",
+ "subarg": "^1.0.0",
+ "through2": "^2.0.0"
+ }
+ },
+ "des.js": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
+ "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
"detect-file": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
"integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
"dev": true
},
+ "detective": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/detective/-/detective-5.1.0.tgz",
+ "integrity": "sha512-TFHMqfOvxlgrfVzTEkNBSh9SvSNX/HfF4OFI2QFGCyPm02EsyILqnUeb5P6q7JZ3SFNTBL5t2sePRgrN4epUWQ==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.3.0",
+ "defined": "^1.0.0",
+ "minimist": "^1.1.1"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
+ "diffie-hellman": {
+ "version": "5.0.3",
+ "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
+ }
+ },
"dom-serializer": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
@@ -741,6 +1237,12 @@
}
}
},
+ "domain-browser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+ "dev": true
+ },
"domelementtype": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
@@ -766,6 +1268,41 @@
"domelementtype": "1"
}
},
+ "duplexer2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -777,6 +1314,21 @@
"safer-buffer": "^2.1.0"
}
},
+ "elliptic": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz",
+ "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.4.0",
+ "brorand": "^1.0.1",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.0"
+ }
+ },
"entities": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
@@ -800,7 +1352,7 @@
},
"es6-promisify": {
"version": "5.0.0",
- "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
"dev": true,
"requires": {
@@ -824,6 +1376,22 @@
"integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
"dev": true
},
+ "events": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz",
+ "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==",
+ "dev": true
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "dev": true,
+ "requires": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
"exit": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
@@ -1082,9 +1650,9 @@
}
},
"fined": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz",
- "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.1.tgz",
+ "integrity": "sha512-jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g==",
"dev": true,
"requires": {
"expand-tilde": "^2.0.2",
@@ -1095,9 +1663,9 @@
}
},
"flagged-respawn": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz",
- "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
+ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
"dev": true
},
"for-in": {
@@ -1173,6 +1741,18 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "get-assigned-identifiers": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
+ "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==",
+ "dev": true
+ },
"get-stdin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
@@ -1293,16 +1873,16 @@
}
},
"grunt-cli": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.1.tgz",
- "integrity": "sha512-UwBRu/QpAjDc53DRLEkyilFdL0zenpxu+fddTIlsF/KJqdNcHaQmvyu1W3cDesZ9rqqZdKK5A8+QDIyLUEWoZQ==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz",
+ "integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==",
"dev": true,
"requires": {
"grunt-known-options": "~1.1.0",
"interpret": "~1.1.0",
"liftoff": "~2.5.0",
"nopt": "~4.0.1",
- "v8flags": "~3.0.2"
+ "v8flags": "~3.1.1"
}
},
"grunt-contrib-concat": {
@@ -1381,14 +1961,14 @@
}
},
"grunt-contrib-qunit": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-3.0.1.tgz",
- "integrity": "sha512-s994+ipKwc+oUUIWaGIw1soyID4pExSGMd/cHQN5h0p8KbIjR1Le3ZC3giSDDKXtZFE0i+Obf0uIjNvjftX2Cw==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-3.1.0.tgz",
+ "integrity": "sha512-mdk8UltH6mxCD63E0hTXMAts42DOi4z4bBBrY7qnuHiShflMF7IueSMYe0zWaZ2dO8mgujh57Zfny2EbigJhRg==",
"dev": true,
"requires": {
"eventemitter2": "^5.0.1",
"p-each-series": "^1.0.0",
- "puppeteer": "1.7.0"
+ "puppeteer": "^1.11.0"
},
"dependencies": {
"eventemitter2": {
@@ -1502,13 +2082,12 @@
}
},
"grunt-shell-spawn": {
- "version": "0.3.10",
- "resolved": "https://registry.npmjs.org/grunt-shell-spawn/-/grunt-shell-spawn-0.3.10.tgz",
- "integrity": "sha1-gbuNRX7EfTGCqH1jCO+EXd+5SI8=",
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/grunt-shell-spawn/-/grunt-shell-spawn-0.4.0.tgz",
+ "integrity": "sha512-lfYvEQjbO1Wv+1Fk3d3XlcEpuQjyXiErZMkiz/i/tDQeMHHGF1LziqA4ZcietBAo/bM2RHdEEUJfnNWt1VRMwQ==",
"dev": true,
"requires": {
- "grunt": ">=0.4.x",
- "sync-exec": "~0.6.2"
+ "grunt": ">=0.4.x"
}
},
"gzip-size": {
@@ -1539,6 +2118,15 @@
"har-schema": "^2.0.0"
}
},
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
"has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
@@ -1586,6 +2174,26 @@
}
}
},
+ "hash-base": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "hash.js": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+ "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
"hasha": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
@@ -1597,6 +2205,17 @@
"pinkie-promise": "^2.0.0"
}
},
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "dev": true,
+ "requires": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
"homedir-polyfill": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
@@ -1618,6 +2237,12 @@
"integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
"dev": true
},
+ "htmlescape": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
+ "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=",
+ "dev": true
+ },
"htmlparser2": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
@@ -1643,6 +2268,12 @@
"sshpk": "^1.7.0"
}
},
+ "https-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+ "dev": true
+ },
"https-proxy-agent": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
@@ -1679,6 +2310,12 @@
"safer-buffer": ">= 2.1.2 < 3"
}
},
+ "ieee754": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz",
+ "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==",
+ "dev": true
+ },
"indent-string": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
@@ -1710,6 +2347,33 @@
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
"dev": true
},
+ "inline-source-map": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz",
+ "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=",
+ "dev": true,
+ "requires": {
+ "source-map": "~0.5.3"
+ }
+ },
+ "insert-module-globals": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz",
+ "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "acorn-node": "^1.5.2",
+ "combine-source-map": "^0.8.0",
+ "concat-stream": "^1.6.1",
+ "is-buffer": "^1.1.0",
+ "path-is-absolute": "^1.0.1",
+ "process": "~0.11.0",
+ "through2": "^2.0.0",
+ "undeclared-identifiers": "^1.1.2",
+ "xtend": "^4.0.0"
+ }
+ },
"interpret": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
@@ -2061,6 +2725,14 @@
}
}
},
+ "json-int64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-int64/-/json-int64-1.0.0.tgz",
+ "integrity": "sha512-yrTg9swToElhEPETLMdZkEzDhbXLs+cxkw/b2rglMPOBlM1DE0utH1EReSMLcnpYJk5iUvD12r0fP2/xHitF5Q==",
+ "requires": {
+ "node-int64": "0.4.0"
+ }
+ },
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
@@ -2075,6 +2747,15 @@
"dev": true,
"optional": true
},
+ "json-stable-stringify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz",
+ "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=",
+ "dev": true,
+ "requires": {
+ "jsonify": "~0.0.0"
+ }
+ },
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
@@ -2092,6 +2773,18 @@
"graceful-fs": "^4.1.6"
}
},
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "dev": true
+ },
+ "jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
+ "dev": true
+ },
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -2126,6 +2819,25 @@
"graceful-fs": "^4.1.9"
}
},
+ "labeled-stream-splicer": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz",
+ "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "isarray": "^2.0.4",
+ "stream-splicer": "^2.0.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz",
+ "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==",
+ "dev": true
+ }
+ }
+ },
"lazy-cache": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
@@ -2181,6 +2893,12 @@
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
},
+ "lodash.memoize": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
+ "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=",
+ "dev": true
+ },
"longest": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
@@ -2229,7 +2947,7 @@
},
"marked": {
"version": "0.3.19",
- "resolved": "http://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
"integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg=="
},
"maxmin": {
@@ -2271,6 +2989,17 @@
}
}
},
+ "md5.js": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
"meow": {
"version": "3.7.0",
"resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
@@ -2318,10 +3047,20 @@
"to-regex": "^3.0.2"
}
},
+ "miller-rabin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
+ }
+ },
"mime": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
- "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz",
+ "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==",
"dev": true
},
"mime-db": {
@@ -2339,6 +3078,18 @@
"mime-db": "~1.37.0"
}
},
+ "minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+ "dev": true
+ },
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -2382,6 +3133,64 @@
"minimist": "0.0.8"
}
},
+ "module-deps": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz",
+ "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "browser-resolve": "^1.7.0",
+ "cached-path-relative": "^1.0.0",
+ "concat-stream": "~1.6.0",
+ "defined": "^1.0.0",
+ "detective": "^5.0.2",
+ "duplexer2": "^0.1.2",
+ "inherits": "^2.0.1",
+ "parents": "^1.0.0",
+ "readable-stream": "^2.0.2",
+ "resolve": "^1.4.0",
+ "stream-combiner2": "^1.1.1",
+ "subarg": "^1.0.0",
+ "through2": "^2.0.0",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "resolve": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
+ "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.5"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -2413,6 +3222,11 @@
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
},
+ "node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs="
+ },
"nopt": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
@@ -2533,6 +3347,12 @@
"wrappy": "1"
}
},
+ "os-browserify": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+ "dev": true
+ },
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
@@ -2573,6 +3393,28 @@
"integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
"dev": true
},
+ "parents": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz",
+ "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=",
+ "dev": true,
+ "requires": {
+ "path-platform": "~0.11.15"
+ }
+ },
+ "parse-asn1": {
+ "version": "5.1.1",
+ "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
+ "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
+ "dev": true,
+ "requires": {
+ "asn1.js": "^4.0.0",
+ "browserify-aes": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3"
+ }
+ },
"parse-filepath": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
@@ -2605,6 +3447,12 @@
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
"dev": true
},
+ "path-browserify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
+ "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
+ "dev": true
+ },
"path-exists": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
@@ -2626,6 +3474,18 @@
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
"dev": true
},
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "dev": true
+ },
+ "path-platform": {
+ "version": "0.11.15",
+ "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz",
+ "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=",
+ "dev": true
+ },
"path-root": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
@@ -2652,6 +3512,19 @@
"pinkie-promise": "^2.0.0"
}
},
+ "pbkdf2": {
+ "version": "3.0.17",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
+ "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
+ "dev": true,
+ "requires": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@@ -2732,6 +3605,12 @@
"meow": "^3.1.0"
}
},
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+ "dev": true
+ },
"process-nextick-args": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
@@ -2758,33 +3637,46 @@
"dev": true,
"optional": true
},
+ "public-encrypt": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+ "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
- "dev": true,
- "optional": true
+ "dev": true
},
"puppeteer": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.7.0.tgz",
- "integrity": "sha512-f+1DxKHPqce6CXUBz2eVO2WcATeVeQSOPG9GYaGObEZDCiCEUwG+gogjMsrvn7he2wHTqNVb5p6RUrwmr8XFBA==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.11.0.tgz",
+ "integrity": "sha512-iG4iMOHixc2EpzqRV+pv7o3GgmU2dNYEMkvKwSaQO/vMZURakwSOn/EYJ6OIRFYOque1qorzIBvrytPIQB3YzQ==",
"dev": true,
"requires": {
- "debug": "^3.1.0",
+ "debug": "^4.1.0",
"extract-zip": "^1.6.6",
"https-proxy-agent": "^2.2.1",
"mime": "^2.0.3",
- "progress": "^2.0.0",
+ "progress": "^2.0.1",
"proxy-from-env": "^1.0.0",
"rimraf": "^2.6.1",
- "ws": "^5.1.1"
+ "ws": "^6.1.0"
},
"dependencies": {
"debug": {
- "version": "3.2.6",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
- "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
@@ -2797,9 +3689,9 @@
"dev": true
},
"progress": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz",
- "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true
}
}
@@ -2811,6 +3703,72 @@
"dev": true,
"optional": true
},
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+ "dev": true
+ },
+ "querystring-es3": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+ "dev": true
+ },
+ "randombytes": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
+ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "randomfill": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "read-only-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz",
+ "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
"read-pkg": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
@@ -3002,6 +3960,16 @@
"glob": "^7.0.5"
}
},
+ "ripemd160": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -3052,6 +4020,26 @@
}
}
},
+ "sha.js": {
+ "version": "2.4.11",
+ "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "shasum": {
+ "version": "1.0.2",
+ "resolved": "http://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz",
+ "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=",
+ "dev": true,
+ "requires": {
+ "json-stable-stringify": "~0.0.0",
+ "sha.js": "~2.4.4"
+ }
+ },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -3067,6 +4055,18 @@
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
"dev": true
},
+ "shell-quote": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz",
+ "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=",
+ "dev": true,
+ "requires": {
+ "array-filter": "~0.0.0",
+ "array-map": "~0.0.0",
+ "array-reduce": "~0.0.0",
+ "jsonify": "~0.0.0"
+ }
+ },
"shelljs": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
@@ -3079,6 +4079,12 @@
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
"dev": true
},
+ "simple-concat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
+ "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=",
+ "dev": true
+ },
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -3314,6 +4320,153 @@
}
}
},
+ "stream-browserify": {
+ "version": "2.0.1",
+ "resolved": "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
+ "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.1",
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "stream-combiner2": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
+ "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=",
+ "dev": true,
+ "requires": {
+ "duplexer2": "~0.1.0",
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "stream-http": {
+ "version": "2.8.3",
+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
+ "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
+ "dev": true,
+ "requires": {
+ "builtin-status-codes": "^3.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.3.6",
+ "to-arraybuffer": "^1.0.0",
+ "xtend": "^4.0.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "stream-splicer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz",
+ "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
@@ -3352,6 +4505,23 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
},
+ "subarg": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
+ "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.1.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -3361,11 +4531,14 @@
"has-flag": "^3.0.0"
}
},
- "sync-exec": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/sync-exec/-/sync-exec-0.6.2.tgz",
- "integrity": "sha1-cX0izFPwzh3vVZQ2LzqJouu5EQU=",
- "dev": true
+ "syntax-error": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz",
+ "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.2.0"
+ }
},
"taffydb": {
"version": "2.6.2",
@@ -3383,8 +4556,58 @@
"version": "2.3.8",
"resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
"dev": true,
- "optional": true
+ "requires": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "timers-browserify": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
+ "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=",
+ "dev": true,
+ "requires": {
+ "process": "~0.11.0"
+ }
+ },
+ "to-arraybuffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+ "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+ "dev": true
},
"to-object-path": {
"version": "0.3.0",
@@ -3445,6 +4668,12 @@
"integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
"dev": true
},
+ "tty-browserify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
+ "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==",
+ "dev": true
+ },
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -3493,12 +4722,30 @@
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
"dev": true
},
+ "umd": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz",
+ "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==",
+ "dev": true
+ },
"unc-path-regex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
"integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
"dev": true
},
+ "undeclared-identifiers": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz",
+ "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.3.0",
+ "get-assigned-identifiers": "^1.2.0",
+ "simple-concat": "^1.0.0",
+ "xtend": "^4.0.1"
+ }
+ },
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
@@ -3622,12 +4869,39 @@
"integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
"dev": true
},
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+ "dev": true
+ }
+ }
+ },
"use": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
"dev": true
},
+ "util": {
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+ "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3"
+ }
+ },
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -3642,9 +4916,9 @@
"optional": true
},
"v8flags": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.2.tgz",
- "integrity": "sha512-6sgSKoFw1UpUPd3cFdF7QGnrH6tDeBgW1F3v9gy8gLY0mlbiBXq8soy8aQpY6xeeCjH5K+JvC62Acp7gtl7wWA==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.2.tgz",
+ "integrity": "sha512-MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw==",
"dev": true,
"requires": {
"homedir-polyfill": "^1.0.1"
@@ -3672,6 +4946,12 @@
"extsprintf": "^1.2.0"
}
},
+ "vm-browserify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz",
+ "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==",
+ "dev": true
+ },
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -3731,9 +5011,9 @@
"dev": true
},
"ws": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
- "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.3.tgz",
+ "integrity": "sha512-tbSxiT+qJI223AP4iLfQbkbxkwdFcneYinM2+x46Gx2wgvbaOMO36czfdfVUBRTHvzAMRhDd98sA5d/BuWbQdg==",
"dev": true,
"requires": {
"async-limiter": "~1.0.0"
@@ -3744,6 +5024,12 @@
"resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-1.0.2.tgz",
"integrity": "sha1-+mv3YqYKQT+z3Y9LA8WyaSONMI8="
},
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ },
"yargs": {
"version": "3.10.0",
"resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
diff --git a/lib/js/package.json b/lib/js/package.json
index 429751d..309622d 100644
--- a/lib/js/package.json
+++ b/lib/js/package.json
@@ -1,19 +1,31 @@
{
"name": "thrift",
- "version": "0.12.1",
+ "version": "0.13.0",
+ "description": "Thrift is a software framework for scalable cross-language services development.",
+ "author": {
+ "name": "Apache Thrift Developers",
+ "email": "dev@thrift.apache.org"
+ },
+ "bugs": "https://issues.apache.org/jira/projects/THRIFT/summary",
+ "homepage": "http://thrift.apache.org",
+ "repository": "https://github.com/apache/thrift",
+ "license": "Apache-2.0",
"devDependencies": {
- "grunt": "^1.0.2",
- "grunt-cli": "^1.2.0",
- "grunt-contrib-concat": "^1.0.1",
- "grunt-contrib-jshint": "^1.0.0",
- "grunt-contrib-qunit": "^3.0.1",
- "grunt-contrib-uglify": "^1.0.1",
- "grunt-jsdoc": "^2.2.1",
- "grunt-shell-spawn": "^0.3.10",
- "jslint": "^0.12.0"
+ "browserify": "~16.2",
+ "grunt": "~1.0",
+ "grunt-cli": "~1.3",
+ "grunt-contrib-concat": "~1.0",
+ "grunt-contrib-jshint": "~2.1",
+ "grunt-contrib-qunit": "~3.1",
+ "grunt-contrib-uglify": "~4.0",
+ "grunt-jsdoc": "~2.3",
+ "grunt-shell-spawn": "~0.4",
+ "jslint": "~0.12",
+ "node-int64": "~0.4.0"
},
"dependencies": {
- "jsdoc": "^3.5.5",
- "nopt": "^4.0.1"
+ "jsdoc": "~3.5",
+ "json-int64": "~1.0",
+ "nopt": "~4.0"
}
}
diff --git a/lib/js/src/thrift.js b/lib/js/src/thrift.js
index 9c8ebff..21a3d65 100644
--- a/lib/js/src/thrift.js
+++ b/lib/js/src/thrift.js
@@ -46,7 +46,7 @@
* @const {string} Version
* @memberof Thrift
*/
- Version: '0.12.1',
+ Version: '0.13.0',
/**
* Thrift IDL type string to Id mapping.
@@ -438,7 +438,12 @@
}
},
context: client,
- success: jQuery.makeArray(args).pop()
+ success: jQuery.makeArray(args).pop(),
+ beforeSend: function (xreq) {
+ Object.keys(thriftTransport.customHeaders).forEach(function (prop) {
+ xreq.setRequestHeader(prop, thriftTransport.customHeaders[prop]);
+ });
+ }
});
return jqXHR;
@@ -1002,7 +1007,11 @@
/** Serializes a number */
writeI64: function(i64) {
- this.tstack.push(i64);
+ if (typeof i64 === 'number') {
+ this.tstack.push(i64);
+ } else {
+ this.tstack.push(Int64Util.toDecimalString(i64));
+ }
},
/** Serializes a number */
@@ -1073,12 +1082,16 @@
this.rstack = [];
this.rpos = [];
- if (typeof JSON !== 'undefined' && typeof JSON.parse === 'function') {
- this.robj = JSON.parse(this.transport.readAll());
+ received = this.transport.readAll();
+
+ if (typeof JSONInt64 !== 'undefined' && typeof JSONInt64.parse === 'function') {
+ this.robj = JSONInt64.parse(received);
+ } else if (typeof JSON !== 'undefined' && typeof JSON.parse === 'function') {
+ this.robj = JSON.parse(received);
} else if (typeof jQuery !== 'undefined') {
- this.robj = jQuery.parseJSON(this.transport.readAll());
+ this.robj = jQuery.parseJSON(received);
} else {
- this.robj = eval(this.transport.readAll());
+ this.robj = eval(received);
}
var r = {};
@@ -1221,7 +1234,6 @@
r.vtype = Thrift.Protocol.RType[map.shift()];
r.size = map.shift();
-
this.rpos.push(this.rstack.length);
this.rstack.push(map.shift());
@@ -1346,8 +1358,54 @@
/** Returns the an object with a value property set to the
next value found in the protocol buffer */
- readI64: function() {
- return this.readI32();
+ readI64: function(f) {
+ if (f === undefined) {
+ f = this.rstack[this.rstack.length - 1];
+ }
+
+ var r = {};
+
+ if (f instanceof Array) {
+ if (f.length === 0) {
+ r.value = undefined;
+ } else {
+ if (!f.isReversed) {
+ f.reverse();
+ f.isReversed = true;
+ }
+ r.value = f.pop();
+ }
+ } else if (f instanceof Object) {
+ var int64Object = true;
+ var objectKeys = Object.keys(f).sort();
+ var int64Keys = ['buffer', 'offset'];
+ if (objectKeys.length !== int64Keys.length) {
+ int64Object = false;
+ }
+ for (var it=0; int64Object && it < objectKeys.length; ++it) {
+ if (objectKeys[it] !== int64Keys[it]) {
+ int64Object = false;
+ }
+ }
+ if (int64Object) {
+ r.value = f;
+ } else {
+ for (var i in f) {
+ if (i === null) {
+ continue;
+ }
+ this.rstack.push(f[i]);
+ delete f[i];
+
+ r.value = i;
+ break;
+ }
+ }
+ } else {
+ r.value = f;
+ this.rstack.pop();
+ }
+ return r;
},
/** Returns the an object with a value property set to the
diff --git a/lib/js/test/build.xml b/lib/js/test/build.xml
index 04c1360..d891b43 100755
--- a/lib/js/test/build.xml
+++ b/lib/js/test/build.xml
@@ -28,13 +28,13 @@
<property name="build" location="build" />
<property name="jar.file" location="${build}/jstest.jar" />
- <!-- the root directory, where you unpack thrift distibution (e.g. thrift-0.x.x.tar.gz) -->
+ <!-- the root directory, where you unpack thrift distibution (e.g.: thrift-0.x.x.tar.gz) -->
<property name="thrift.dir" location="../../../" />
<property name="thrift.java.dir" location="${thrift.dir}/lib/java" />
<property name="build.tools.dir" location="${thrift.java.dir}/build/tools/"/>
<property file="${basedir}/build.properties"/>
- <!-- Include the base java properties file -->
+ <!-- Include the base Java properties file -->
<property file="${thrift.java.dir}/gradle.properties" />
<property name="thrift.compiler" location="${thrift.dir}/compiler/cpp/thrift" />
@@ -73,7 +73,7 @@
</condition>
You need libthrift*.jar and libthrift*test.jar located at
${thrift.java.dir}/build/libs
- Did you compile Thrift Java library and its test suite by "ant compile-test"?
+ Did you compile Thrift Java library and its test suite by "make check"?
</fail>
<fail>
<condition>
@@ -187,7 +187,6 @@
-->
<jsl:jslint options="evil,forin,browser,bitwise,regexp,newcap,immed" encoding="UTF-8">
<formatter type="plain" />
- <fileset dir="${genjs}" includes="**/*.js" />
<fileset dir="../src" includes="thrift.js" />
<!-- issues with unsafe character -->
diff --git a/lib/js/test/test-deep-constructor.html b/lib/js/test/test-deep-constructor.html
index 4c5fb02..462481a 100755
--- a/lib/js/test/test-deep-constructor.html
+++ b/lib/js/test/test-deep-constructor.html
@@ -22,6 +22,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Thrift Javascript Bindings: Unit Test</title>
+ <script src="build/js/lib/JSONInt64.js" type="text/javascript" charset="utf-8"></script>
<script src="build/js/thrift.js" type="text/javascript" charset="utf-8"></script>
<script src="gen-js/JsDeepConstructorTest_types.js" type="text/javascript" charset="utf-8"></script>
<!-- jQuery -->
@@ -35,7 +36,7 @@
<script type="text/javascript" src="deep-constructor.test.js" charset="utf-8"></script>
</head>
<body>
- <h1 id="qunit-header">Thrift Javascript Bindings: Deep Constructor Test (<a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=test/JsDeepConstructorTest.thrift;hb=HEAD">JsDeepConstructorTest.thrift</a>)</h1>
+ <h1 id="qunit-header">Thrift Javascript Bindings: Deep Constructor Test (<a href="https://github.com/apache/thrift/blob/master/test/JsDeepConstructorTest.thrift">JsDeepConstructorTest.thrift</a>)</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
diff --git a/lib/js/test/test-double-rendering.html b/lib/js/test/test-double-rendering.html
index 240cb39..7a430a5 100644
--- a/lib/js/test/test-double-rendering.html
+++ b/lib/js/test/test-double-rendering.html
@@ -29,11 +29,11 @@
<script src="gen-js/DoubleConstantsTest_types.js" type="text/javascript" charset="utf-8"></script>
<!-- jQuery -->
- <script type="text/javascript" src="../node_modules/jquery/dist/jquery.js" charset="utf-8"></script>
+ <script type="text/javascript" src="build/js/lib/jquery.js" charset="utf-8"></script>
<!-- QUnit Test framework-->
- <script type="text/javascript" src="../node_modules/qunit/qunit/qunit.js" charset="utf-8"></script>
- <link rel="stylesheet" href="../node_modules/qunit/qunit/qunit.css" type="text/css" media="screen" />
+ <script type="text/javascript" src="build/js/lib/qunit.js" charset="utf-8"></script>
+ <link rel="stylesheet" href="build/js/lib/qunit.css" type="text/css" media="screen" />
<!-- the Test Suite-->
<script type="text/javascript" src="test-double-rendering.js" charset="utf-8"></script>
diff --git a/lib/js/test/test-double-rendering.js b/lib/js/test/test-double-rendering.js
index b4b79b8..1790c1b 100644
--- a/lib/js/test/test-double-rendering.js
+++ b/lib/js/test/test-double-rendering.js
@@ -20,29 +20,11 @@
/*
* JavaScript test suite for double constants inside
- * DebugProtoTest.thrift. These tests will run against Normal (-gen js)
+ * DoubleConstantsTest.thrift. These tests will run against Normal (-gen js)
* Apache Thrift interfaces.
*
- * Synchronous blocking calls should be identical in both
- * Normal and jQuery interfaces. All synchronous tests belong
- * here.
- *
- * Asynchronous success callbacks passed as the last parameter
- * of an RPC call should be identical in both Normal and jQuery
- * interfaces. Async success tests belong here.
- *
- * Asynchronous exception processing is different in Normal
- * and jQuery interfaces. Such tests belong in the test-nojq.js
- * or test-jq.js files respectively. jQuery specific XHR object
- * tests also belong in test-jq.js. Do not create any jQuery
- * dependencies in this file or in test-nojq.js
- *
* To compile client code for this test use:
- * $ thrift -gen js ThriftTest.thrift
- * $ thrift -gen js DebugProtoTest.thrift
- *
- * See also:
- * ++ test-nojq.js for "-gen js" only tests
+ * $ thrift -gen js DoubleConstantsTest.thrift
*/
// double assertion threshold
diff --git a/lib/js/test/test-es6.html b/lib/js/test/test-es6.html
index 5f55da7..f0b8dd9 100644
--- a/lib/js/test/test-es6.html
+++ b/lib/js/test/test-es6.html
@@ -22,6 +22,9 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Thrift Javascript Bindings: Unit Test</title>
+ <script src="build/js/lib/Int64.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/js/lib/Int64Util.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/js/lib/JSONInt64.js" type="text/javascript" charset="utf-8"></script>
<script src="build/js/thrift.js" type="text/javascript" charset="utf-8"></script>
<script src="gen-js-es6/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>
<script src="gen-js-es6/ThriftTest.js" type="text/javascript" charset="utf-8"></script>
@@ -46,7 +49,7 @@
<script type="text/javascript" src="test-es6.js" charset="utf-8"></script>
</head>
<body>
- <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=test/ThriftTest.thrift;hb=HEAD">ThriftTest.thrift</a>)</h1>
+ <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://github.com/apache/thrift/blob/master/test/ThriftTest.thrift">ThriftTest.thrift</a>)</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
diff --git a/lib/js/test/test-int64.html b/lib/js/test/test-int64.html
new file mode 100644
index 0000000..bcb05fb
--- /dev/null
+++ b/lib/js/test/test-int64.html
@@ -0,0 +1,56 @@
++<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+ 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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Int64 Constants in JS: Unit Test</title>
+
+ <script src="build/js/thrift.js" type="text/javascript" charset="utf-8"></script>
+ <!-- browserified node-int64 -->
+ <script src="build/js/lib/Int64.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/js/lib/JSONInt64.js" type="text/javascript" charset="utf-8"></script>
+ <!-- int64 constants to check -->
+ <script src="gen-js/Int64Test_types.js" type="text/javascript" charset="utf-8"></script>
+
+ <!-- jQuery -->
+ <script type="text/javascript" src="build/js/lib/jquery.js" charset="utf-8"></script>
+
+ <!-- QUnit Test framework-->
+ <script type="text/javascript" src="build/js/lib/qunit.js" charset="utf-8"></script>
+ <link rel="stylesheet" href="build/js/lib/qunit.css" type="text/css" media="screen" />
+
+ <!-- the Test Suite-->
+ <script type="text/javascript" src="test-int64.js" charset="utf-8"></script>
+ </head>
+<body>
+ <h1 id="qunit-header">Int64 Constants in JS: Unit Test</h1>
+ <h2 id="qunit-banner"></h2>
+ <div id="qunit-testrunner-toolbar"></div>
+ <h2 id="qunit-userAgent"></h2>
+ <ol id="qunit-tests"><li><!-- get valid xhtml strict--></li></ol>
+ <!-- Uncomment this to check the validity. This significantly slows down the test.
+ <p>
+ <a href="http://validator.w3.org/check/referer"><img
+ src="http://www.w3.org/Icons/valid-xhtml10"
+ alt="Valid XHTML 1.0!" height="31" width="88" /></a>
+ </p>
+ -->
+</body>
+</html>
diff --git a/lib/js/test/test-int64.js b/lib/js/test/test-int64.js
new file mode 100644
index 0000000..cf7e828
--- /dev/null
+++ b/lib/js/test/test-int64.js
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+ /* jshint -W100 */
+
+// Work around for old API used by QUnitAdapter of jsTestDriver
+if (typeof QUnit.log == 'function') {
+ // When using real QUnit (fron PhantomJS) log failures to console
+ QUnit.log(function(details) {
+ if (!details.result) {
+ console.log('======== FAIL ========');
+ console.log('TestName: ' + details.name);
+ if (details.message) console.log(details.message);
+ console.log('Expected: ' + details.expected);
+ console.log('Actual : ' + details.actual);
+ console.log('======================');
+ }
+ });
+}
+
+QUnit.module('Int64');
+
+ QUnit.test('Int64', function(assert) {
+ console.log('Int64 test -- starts');
+ const EXPECTED_SMALL_INT64_AS_NUMBER = 42;
+ const EXPECTED_SMALL_INT64 = new Int64(42);
+ const EXPECTED_MAX_JS_SAFE_INT64 = new Int64(Number.MAX_SAFE_INTEGER);
+ const EXPECTED_MIN_JS_SAFE_INT64 = new Int64(Number.MIN_SAFE_INTEGER);
+ const EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64 = new Int64("0020000000000000"); // hex-encoded
+ const EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64 = new Int64("ffe0000000000000"); // hex-encoded 2's complement
+ const EXPECTED_MAX_SIGNED_INT64 = new Int64("7fffffffffffffff"); // hex-encoded
+ const EXPECTED_MIN_SIGNED_INT64 = new Int64("8000000000000000"); // hex-encoded 2's complement
+ const EXPECTED_INT64_LIST = [
+ EXPECTED_SMALL_INT64,
+ EXPECTED_MAX_JS_SAFE_INT64,
+ EXPECTED_MIN_JS_SAFE_INT64,
+ EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64,
+ EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64,
+ EXPECTED_MAX_SIGNED_INT64,
+ EXPECTED_MIN_SIGNED_INT64
+ ];
+
+ assert.ok(EXPECTED_SMALL_INT64.equals(Int64Test.SMALL_INT64));
+ assert.ok(EXPECTED_MAX_JS_SAFE_INT64.equals(Int64Test.MAX_JS_SAFE_INT64));
+ assert.ok(EXPECTED_MIN_JS_SAFE_INT64.equals(Int64Test.MIN_JS_SAFE_INT64));
+ assert.ok(
+ EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64.equals(
+ Int64Test.MAX_JS_SAFE_PLUS_ONE_INT64
+ )
+ );
+ assert.ok(
+ EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64.equals(
+ Int64Test.MIN_JS_SAFE_MINUS_ONE_INT64
+ )
+ );
+ assert.ok(EXPECTED_MAX_SIGNED_INT64.equals(Int64Test.MAX_SIGNED_INT64));
+ assert.ok(EXPECTED_MIN_SIGNED_INT64.equals(Int64Test.MIN_SIGNED_INT64));
+ assert.equal(
+ EXPECTED_SMALL_INT64_AS_NUMBER,
+ Int64Test.SMALL_INT64.toNumber()
+ );
+ assert.equal(
+ Number.MAX_SAFE_INTEGER,
+ Int64Test.MAX_JS_SAFE_INT64.toNumber()
+ );
+ assert.equal(
+ Number.MIN_SAFE_INTEGER,
+ Int64Test.MIN_JS_SAFE_INT64.toNumber()
+ );
+
+ for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) {
+ assert.ok(EXPECTED_INT64_LIST[i].equals(Int64Test.INT64_LIST[i]));
+ }
+
+ for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i){
+ let int64Object = EXPECTED_INT64_LIST[i];
+ assert.ok(Int64Test.INT64_2_INT64_MAP[JSONInt64.toDecimalString(int64Object)].equals(int64Object));
+ }
+
+ console.log('Int64 test -- ends');
+ });
+
diff --git a/lib/js/test/test-nojq.html b/lib/js/test/test-nojq.html
index 9eec7fc..37b3eb8 100644
--- a/lib/js/test/test-nojq.html
+++ b/lib/js/test/test-nojq.html
@@ -22,6 +22,9 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Thrift Javascript Bindings: Unit Test</title>
+ <script src="build/js/lib/Int64.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/js/lib/Int64Util.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/js/lib/JSONInt64.js" type="text/javascript" charset="utf-8"></script>
<script src="build/js/thrift.js" type="text/javascript" charset="utf-8"></script>
<script src="gen-js/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>
<script src="gen-js/ThriftTest.js" type="text/javascript" charset="utf-8"></script>
@@ -35,7 +38,7 @@
<script type="text/javascript" src="test-nojq.js" charset="utf-8"></script>
</head>
<body>
- <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=test/ThriftTest.thrift;hb=HEAD">ThriftTest.thrift</a>)</h1>
+ <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://github.com/apache/thrift/blob/master/test/ThriftTest.thrift">ThriftTest.thrift</a>)</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
diff --git a/lib/js/test/test.html b/lib/js/test/test.html
index af035b6..85c8395 100755
--- a/lib/js/test/test.html
+++ b/lib/js/test/test.html
@@ -22,6 +22,9 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Thrift Javascript Bindings: Unit Test</title>
+ <script src="build/js/lib/Int64.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/js/lib/Int64Util.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/js/lib/JSONInt64.js" type="text/javascript" charset="utf-8"></script>
<script src="build/js/thrift.js" type="text/javascript" charset="utf-8"></script>
<script src="gen-js-jquery/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>
<script src="gen-js-jquery/ThriftTest.js" type="text/javascript" charset="utf-8"></script>
@@ -38,7 +41,7 @@
<script type="text/javascript" src="test-jq.js" charset="utf-8"></script>
</head>
<body>
- <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=test/ThriftTest.thrift;hb=HEAD">ThriftTest.thrift</a>)</h1>
+ <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://github.com/apache/thrift/blob/master/test/ThriftTest.thrift">ThriftTest.thrift</a>)</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
diff --git a/lib/js/test/test.js b/lib/js/test/test.js
index a86a509..35ed6ff 100755
--- a/lib/js/test/test.js
+++ b/lib/js/test/test.js
@@ -51,6 +51,9 @@
const protocol = new Thrift.Protocol(transport);
const client = new ThriftTest.ThriftTestClient(protocol);
+const int64_2_pow_60 = new Int64('1000000000000000');
+const int64_minus_2_pow_60 = new Int64('f000000000000000');
+
// Work around for old API used by QUnitAdapter of jsTestDriver
if (typeof QUnit.log == 'function') {
// When using real QUnit (fron PhantomJS) log failures to console
@@ -132,9 +135,12 @@
});
QUnit.test('I64', function(assert) {
assert.equal(client.testI64(0), 0);
- //This is usually 2^60 but JS cannot represent anything over 2^52 accurately
- assert.equal(client.testI64(Math.pow(2, 52)), Math.pow(2, 52));
- assert.equal(client.testI64(-Math.pow(2, 52)), -Math.pow(2, 52));
+
+ let int64_2_pow_60_result = client.testI64(int64_2_pow_60);
+ assert.ok(int64_2_pow_60.equals(int64_2_pow_60_result));
+
+ let int64_minus_2_pow_60_result = client.testI64(int64_minus_2_pow_60);
+ assert.ok(int64_minus_2_pow_60.equals(int64_minus_2_pow_60_result));
});
@@ -145,15 +151,14 @@
structTestInput.string_thing = 'worked';
structTestInput.byte_thing = 0x01;
structTestInput.i32_thing = Math.pow(2, 30);
- //This is usually 2^60 but JS cannot represent anything over 2^52 accurately
- structTestInput.i64_thing = Math.pow(2, 52);
+ structTestInput.i64_thing = int64_2_pow_60;
const structTestOutput = client.testStruct(structTestInput);
assert.equal(structTestOutput.string_thing, structTestInput.string_thing);
assert.equal(structTestOutput.byte_thing, structTestInput.byte_thing);
assert.equal(structTestOutput.i32_thing, structTestInput.i32_thing);
- assert.equal(structTestOutput.i64_thing, structTestInput.i64_thing);
+ assert.ok(structTestOutput.i64_thing.equals(structTestInput.i64_thing));
assert.equal(JSON.stringify(structTestOutput), JSON.stringify(structTestInput));
});
@@ -163,8 +168,7 @@
xtrTestInput.string_thing = 'worked';
xtrTestInput.byte_thing = 0x01;
xtrTestInput.i32_thing = Math.pow(2, 30);
- //This is usually 2^60 but JS cannot represent anything over 2^52 accurately
- xtrTestInput.i64_thing = Math.pow(2, 52);
+ xtrTestInput.i64_thing = int64_2_pow_60;
const nestTestInput = new ThriftTest.Xtruct2();
nestTestInput.byte_thing = 0x02;
@@ -177,7 +181,7 @@
assert.equal(nestTestOutput.struct_thing.string_thing, nestTestInput.struct_thing.string_thing);
assert.equal(nestTestOutput.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing);
assert.equal(nestTestOutput.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing);
- assert.equal(nestTestOutput.struct_thing.i64_thing, nestTestInput.struct_thing.i64_thing);
+ assert.ok(nestTestOutput.struct_thing.i64_thing.equals(nestTestInput.struct_thing.i64_thing));
assert.equal(nestTestOutput.i32_thing, nestTestInput.i32_thing);
assert.equal(JSON.stringify(nestTestOutput), JSON.stringify(nestTestInput));
@@ -252,7 +256,7 @@
structTestInput.string_thing = 'worked';
structTestInput.byte_thing = 0x01;
structTestInput.i32_thing = Math.pow(2, 30);
- structTestInput.i64_thing = Math.pow(2, 52);
+ structTestInput.i64_thing = int64_2_pow_60;
const structTestOutput = modifiedClient.testStruct(structTestInput);
@@ -260,7 +264,7 @@
assert.equal(structTestOutput.string_thing, structTestInput.string_thing);
assert.equal(structTestOutput.changed, null);
assert.equal(structTestOutput.i32_thing, structTestInput.i32_thing);
- assert.equal(structTestOutput.i64_thing, structTestInput.i64_thing);
+ assert.ok(structTestOutput.i64_thing.equals(structTestInput.i64_thing));
});
@@ -332,13 +336,13 @@
'string_thing': 'Goodbye4',
'byte_thing': 4,
'i32_thing': 4,
- 'i64_thing': 4
+ 'i64_thing': new Int64(4)
},
{
'string_thing': 'Hello2',
'byte_thing': 2,
'i32_thing': 2,
- 'i64_thing': 2
+ 'i64_thing': new Int64(2)
}]
};
QUnit.test('testInsanity', function(assert) {
@@ -401,15 +405,13 @@
assert.expect(2);
const done = assert.async(2);
- //This is usually 2^60 but JS cannot represent anything over 2^52 accurately
- client.testI64(Math.pow(2, 52), function(result) {
- assert.equal(result, Math.pow(2, 52));
+ client.testI64(int64_2_pow_60, function(result) {
+ assert.ok(int64_2_pow_60.equals(result));
done();
});
- //This is usually 2^60 but JS cannot represent anything over 2^52 accurately
- client.testI64(Math.pow(-2, 52), function(result) {
- assert.equal(result, Math.pow(-2, 52));
+ client.testI64(int64_minus_2_pow_60, function(result) {
+ assert.ok(int64_minus_2_pow_60.equals(result));
done();
});
});
diff --git a/lib/js/test/test_handler.js b/lib/js/test/test_handler.js
index af5f7bd..8ba296b 100644
--- a/lib/js/test/test_handler.js
+++ b/lib/js/test/test_handler.js
@@ -24,6 +24,7 @@
const genFolder = es6Mode ? 'gen-nodejs-es6' : 'gen-nodejs';
const ttypes = require(`./${genFolder}/ThriftTest_types`);
const TException = require('../../nodejs/lib/thrift').TException;
+const Int64 = require('node-int64');
exports.ThriftTestHandler = {
testVoid: function(result) {
@@ -122,13 +123,13 @@
hello.string_thing = 'Hello2';
hello.byte_thing = 2;
hello.i32_thing = 2;
- hello.i64_thing = 2;
+ hello.i64_thing = new Int64(2);
const goodbye = new ttypes.Xtruct();
goodbye.string_thing = 'Goodbye4';
goodbye.byte_thing = 4;
goodbye.i32_thing = 4;
- goodbye.i64_thing = 4;
+ goodbye.i64_thing = new Int64(4);
const crazy = new ttypes.Insanity();
crazy.userMap = [];
diff --git a/lib/js/test/testws.html b/lib/js/test/testws.html
index 1edf0e0..5ff9f22 100644
--- a/lib/js/test/testws.html
+++ b/lib/js/test/testws.html
@@ -22,6 +22,9 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Thrift Javascript Bindings: Unit Test</title>
+ <script src="build/js/lib/Int64.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/js/lib/Int64Util.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/js/lib/JSONInt64.js" type="text/javascript" charset="utf-8"></script>
<script src="build/js/thrift.js" type="text/javascript" charset="utf-8"></script>
<script src="gen-js/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>
<script src="gen-js/ThriftTest.js" type="text/javascript" charset="utf-8"></script>
@@ -46,7 +49,7 @@
<script type="text/javascript" src="test-async.js" charset="utf-8"></script>
</head>
<body>
- <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=test/ThriftTest.thrift;hb=HEAD">ThriftTest.thrift</a>)</h1>
+ <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://github.com/apache/thrift/blob/master/test/ThriftTest.thrift">ThriftTest.thrift</a>)</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
diff --git a/lib/json/Makefile.am b/lib/json/Makefile.am
index 1051b9b..6c8c0ce 100644
--- a/lib/json/Makefile.am
+++ b/lib/json/Makefile.am
@@ -17,13 +17,17 @@
# under the License.
#
-SUBDIRS =
-
if WITH_JAVA
# Schema validation test depends on java
-SUBDIRS += test
+SUBDIRS = test
endif
+clean-local:
+ $(RM) -r test/build/
+
+dist-hook:
+ $(RM) -r $(distdir)/test/build/
+
EXTRA_DIST = \
schema.json \
test
diff --git a/lib/lua/THttpTransport.lua b/lib/lua/THttpTransport.lua
index df957cd..2951db7 100644
--- a/lib/lua/THttpTransport.lua
+++ b/lib/lua/THttpTransport.lua
@@ -25,7 +25,7 @@
wBuf = '',
rBuf = '',
CRLF = '\r\n',
- VERSION = '0.12.1',
+ VERSION = version,
isServer = true
}
diff --git a/lib/lua/Thrift.lua b/lib/lua/Thrift.lua
index 789a20c..a948b3d 100644
--- a/lib/lua/Thrift.lua
+++ b/lib/lua/Thrift.lua
@@ -48,7 +48,7 @@
return count
end
-version = '0.12.1'
+version = '0.13.0'
TType = {
STOP = 0,
diff --git a/lib/netcore/Makefile.am b/lib/netcore/Makefile.am
index caf3f34..4e2d6a5 100644
--- a/lib/netcore/Makefile.am
+++ b/lib/netcore/Makefile.am
@@ -17,18 +17,35 @@
# under the License.
#
-SUBDIRS = .
-
all-local:
$(DOTNETCORE) build
check-local:
$(DOTNETCORE) test Tests/Thrift.Tests/Thrift.Tests.csproj
- ${DOTNETCORE} test Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
+ $(DOTNETCORE) test Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
clean-local:
$(RM) -r Thrift/bin
$(RM) -r Thrift/obj
+ $(RM) -r Tests/Thrift.Tests/bin
+ $(RM) -r Tests/Thrift.Tests/obj
+ $(RM) -r Tests/Thrift.IntegrationTests/bin
+ $(RM) -r Tests/Thrift.IntegrationTests/obj
+ $(RM) -r Tests/Thrift.PublicInterfaces.Compile.Tests/bin
+ $(RM) -r Tests/Thrift.PublicInterfaces.Compile.Tests/obj
+
+dist-hook:
+ $(RM) -r $(distdir)/Thrift/bin
+ $(RM) -r $(distdir)/Thrift/obj
+ $(RM) -r $(distdir)/Tests/Thrift.Tests/bin
+ $(RM) -r $(distdir)/Tests/Thrift.Tests/obj
+ $(RM) -r $(distdir)/Tests/Thrift.IntegrationTests/bin
+ $(RM) -r $(distdir)/Tests/Thrift.IntegrationTests/obj
+ $(RM) -r $(distdir)/Tests/Thrift.PublicInterfaces.Compile.Tests/bin
+ $(RM) -r $(distdir)/Tests/Thrift.PublicInterfaces.Compile.Tests/obj
+
+DISTCLEANFILES = \
+ Makefile.in
EXTRA_DIST = \
README.md \
diff --git a/lib/netcore/README.md b/lib/netcore/README.md
index 94b047f..bcd25b9 100644
--- a/lib/netcore/README.md
+++ b/lib/netcore/README.md
@@ -2,6 +2,11 @@
Thrift client library ported to Microsoft .Net Core
+# Deprecation notice
+
+Per [THRIFT-4723](https://issues.apache.org/jira/browse/THRIFT-4723), both CSharp and Netcore targets are deprecated
+and will be removed with the next release. Migrate to the [NetStd language target](../netstd/README.md) instead.
+
# Content
- Tests/Thrift.PublicInterfaces.Compile.Tests - project for checking public interfaces during adding changes to Thrift library
- Thrift - Thrift library
diff --git a/lib/netcore/Thrift/Properties/AssemblyInfo.cs b/lib/netcore/Thrift/Properties/AssemblyInfo.cs
index 11e66f9..0f433b6 100644
--- a/lib/netcore/Thrift/Properties/AssemblyInfo.cs
+++ b/lib/netcore/Thrift/Properties/AssemblyInfo.cs
@@ -52,5 +52,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("0.12.1.0")]
-[assembly: AssemblyFileVersion("0.12.1.0")]
+[assembly: AssemblyVersion("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/lib/netcore/Thrift/Transports/Client/THttpClientTransport.cs b/lib/netcore/Thrift/Transports/Client/THttpClientTransport.cs
index d24e537..949bee7 100644
--- a/lib/netcore/Thrift/Transports/Client/THttpClientTransport.cs
+++ b/lib/netcore/Thrift/Transports/Client/THttpClientTransport.cs
@@ -149,7 +149,7 @@
}
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-thrift"));
- httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("THttpClientTransport", "0.12.1"));
+ httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("THttpClientTransport", "0.13.0"));
if (CustomHeaders != null)
{
diff --git a/lib/netcore/Thrift/Transports/Client/TStreamClientTransport.cs b/lib/netcore/Thrift/Transports/Client/TStreamClientTransport.cs
index f7164f0..be2011e 100644
--- a/lib/netcore/Thrift/Transports/Client/TStreamClientTransport.cs
+++ b/lib/netcore/Thrift/Transports/Client/TStreamClientTransport.cs
@@ -82,7 +82,7 @@
if (OutputStream == null)
{
throw new TTransportException(TTransportException.ExceptionType.NotOpen,
- "Cannot read from null inputstream");
+ "Cannot write to null outputstream");
}
await OutputStream.WriteAsync(buffer, offset, length, cancellationToken);
diff --git a/lib/netstd/Makefile.am b/lib/netstd/Makefile.am
new file mode 100644
index 0000000..f6faaca
--- /dev/null
+++ b/lib/netstd/Makefile.am
@@ -0,0 +1,58 @@
+#
+# 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.
+#
+
+SUBDIRS = .
+
+all-local:
+ $(DOTNETCORE) build
+
+check-local:
+ $(DOTNETCORE) test Tests/Thrift.Tests/Thrift.Tests.csproj
+ ${DOTNETCORE} test Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
+
+clean-local:
+ $(RM) -r Thrift/bin
+ $(RM) -r Thrift/obj
+
+EXTRA_DIST = \
+ README.md \
+ Tests/Thrift.IntegrationTests/Protocols \
+ Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj \
+ Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj \
+ Tests/Thrift.PublicInterfaces.Compile.Tests/Properties/AssemblyInfo.cs \
+ Tests/Thrift.PublicInterfaces.Compile.Tests/CassandraTest.thrift \
+ Tests/Thrift.Tests/Thrift.Tests.csproj \
+ Tests/Thrift.Tests/Protocols \
+ Tests/Thrift.Tests/Collections \
+ Thrift/TApplicationException.cs \
+ Thrift/TBaseClient.cs \
+ Thrift/TException.cs \
+ Thrift/Thrift.csproj \
+ Thrift/Collections \
+ Thrift/Processor \
+ Thrift/Properties \
+ Thrift/Protocol \
+ Thrift/Server \
+ Thrift/Transport \
+ Thrift.sln \
+ build.cmd \
+ build.sh \
+ runtests.cmd \
+ runtests.sh
+
\ No newline at end of file
diff --git a/lib/netstd/README.md b/lib/netstd/README.md
new file mode 100644
index 0000000..88ba73a
--- /dev/null
+++ b/lib/netstd/README.md
@@ -0,0 +1,54 @@
+# Apache Thrift netstd
+
+Thrift client library for Microsoft .NET Standard
+
+# Build the library
+
+## How to build on Windows
+- Get Thrift IDL compiler executable, add to some folder and add path to this folder into PATH variable
+- Open the Thrift.sln project with Visual Studio and build.
+or
+- Build with scripts
+
+## How to build on Unix/Linux
+- Ensure you have .NET SDK >= 2.0 installed, or use the [Ubuntu docker image](../../build/docker/README.md)
+- Follow common automake build practice: `./ bootstrap && ./ configure && make`
+
+## Known issues
+- In trace logging mode you can see some not important internal exceptions
+
+# Migration to netstd
+
+## ... from netcore
+
+If you are migrating your code from netcore library, you will have to:
+
+- Switch to `thrift -gen netstd`
+- the following compiler flags are no longer needed or supported: `hashcode` is now standard, while `nullable` is no longer supported.
+- the `Thrift.Transport` and `Thrift.Protocol` namespaces now use the singular form
+- add `using Thrift.Processor;` in the server code where appropriate
+- rename all `T*ClientTransport` to `T*Transport`
+- rename all `TBaseServer` occurrences in your code to `TServer`
+- the `SingletonTProcessorFactory` is now called `TSingletonProcessorFactory`
+- and the `AsyncBaseServer` is now the `TSimpleAsyncServer`
+
+You may wonder why we changed so many names. The naming scheme has been revised for two reasons: First, we want to get back the established, well-known naming consistency across the Thrift libraries which the netcore library did not fully respect. Second, by achieving that first objective, we get the additional benefit of making migration at least a bit easier for C# projects.
+
+## ... from csharp
+
+Because of the different environment requirements, migration from C# takes slightly more efforts. While the code changes related to Thrift itself are moderate, you may need to upgrade certain dependencies, components or even modules to more recent versions.
+
+1. Client and server applications must use at least framework 4.6.1, any version below will not work.
+1. Switch to `thrift -gen netstd`. The following compiler flags are no longer needed or supported: `hashcode` and `async` are now standard, while `nullable` is no longer supported.
+1. [Familiarize yourself with the `async/await` model](https://msdn.microsoft.com/en-us/magazine/jj991977.aspx), if you have not already done so. As netstd does not support `ISync` anymore, async is mandatory. The synchronous model is simply no longer available (that's also the reason why we don't need the `async` flag anymore).
+1. Consider proper use of `cancellationToken` parameters. They are optional but may be quite helpful.
+1. As you probably already guessed, there are a few names that have been changed:
+- add `using Thrift.Processor;` in the server code where appropriate
+- the `TServerSocket` is now called `TServerSocketTransport`
+- change `IProtocolFactory` into `ITProtocolFactory`
+- if you are looking for `TSimpleServer`, try `TSimpleAsyncServer` instead
+- similarly, the `TThreadPoolServer` is now a `TThreadPoolAsyncServer`
+- the server's `Serve()` method does now `ServeAsync()`
+- In case you are using Thrift server event handlers: the `SetEventHandler` method now starts with an uppercase letter
+- and you will also have to revise the method names of all `TServerEventHandler` descendants you have in your code
+
diff --git a/lib/netstd/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs b/lib/netstd/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs
new file mode 100644
index 0000000..b1f8418
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.IntegrationTests/Protocols/ProtocolsOperationsTests.cs
@@ -0,0 +1,502 @@
+// 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.
+
+using System;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using KellermanSoftware.CompareNetObjects;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Protocol;
+using Thrift.Protocol.Entities;
+using Thrift.Transport.Client;
+
+namespace Thrift.IntegrationTests.Protocols
+{
+ [TestClass]
+ public class ProtocolsOperationsTests
+ {
+ private readonly CompareLogic _compareLogic = new CompareLogic();
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol), TMessageType.Call)]
+ [DataRow(typeof(TBinaryProtocol), TMessageType.Exception)]
+ [DataRow(typeof(TBinaryProtocol), TMessageType.Oneway)]
+ [DataRow(typeof(TBinaryProtocol), TMessageType.Reply)]
+ [DataRow(typeof(TCompactProtocol), TMessageType.Call)]
+ [DataRow(typeof(TCompactProtocol), TMessageType.Exception)]
+ [DataRow(typeof(TCompactProtocol), TMessageType.Oneway)]
+ [DataRow(typeof(TCompactProtocol), TMessageType.Reply)]
+ [DataRow(typeof(TJsonProtocol), TMessageType.Call)]
+ [DataRow(typeof(TJsonProtocol), TMessageType.Exception)]
+ [DataRow(typeof(TJsonProtocol), TMessageType.Oneway)]
+ [DataRow(typeof(TJsonProtocol), TMessageType.Reply)]
+ public async Task WriteReadMessage_Test(Type protocolType, TMessageType messageType)
+ {
+ var expected = new TMessage(nameof(TMessage), messageType, 1);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteMessageBeginAsync(expected);
+ await protocol.WriteMessageEndAsync();
+
+ stream.Seek(0, SeekOrigin.Begin);
+
+ var actualMessage = await protocol.ReadMessageBeginAsync();
+ await protocol.ReadMessageEndAsync();
+
+ var result = _compareLogic.Compare(expected, actualMessage);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ [ExpectedException(typeof(Exception))]
+ public async Task WriteReadStruct_Test(Type protocolType)
+ {
+ var expected = new TStruct(nameof(TStruct));
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteStructBeginAsync(expected);
+ await protocol.WriteStructEndAsync();
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadStructBeginAsync();
+ await protocol.ReadStructEndAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ [ExpectedException(typeof(Exception))]
+ public async Task WriteReadField_Test(Type protocolType)
+ {
+ var expected = new TField(nameof(TField), TType.String, 1);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteFieldBeginAsync(expected);
+ await protocol.WriteFieldEndAsync();
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadFieldBeginAsync();
+ await protocol.ReadFieldEndAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadMap_Test(Type protocolType)
+ {
+ var expected = new TMap(TType.String, TType.String, 1);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteMapBeginAsync(expected);
+ await protocol.WriteMapEndAsync();
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadMapBeginAsync();
+ await protocol.ReadMapEndAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadList_Test(Type protocolType)
+ {
+ var expected = new TList(TType.String, 1);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteListBeginAsync(expected);
+ await protocol.WriteListEndAsync();
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadListBeginAsync();
+ await protocol.ReadListEndAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadSet_Test(Type protocolType)
+ {
+ var expected = new TSet(TType.String, 1);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteSetBeginAsync(expected);
+ await protocol.WriteSetEndAsync();
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadSetBeginAsync();
+ await protocol.ReadSetEndAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadBool_Test(Type protocolType)
+ {
+ var expected = true;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteBoolAsync(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadBoolAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadByte_Test(Type protocolType)
+ {
+ var expected = sbyte.MaxValue;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteByteAsync(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadByteAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadI16_Test(Type protocolType)
+ {
+ var expected = short.MaxValue;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteI16Async(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadI16Async();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadI32_Test(Type protocolType)
+ {
+ var expected = int.MaxValue;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteI32Async(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadI32Async();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadI64_Test(Type protocolType)
+ {
+ var expected = long.MaxValue;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteI64Async(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadI64Async();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadDouble_Test(Type protocolType)
+ {
+ var expected = double.MaxValue;
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteDoubleAsync(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadDoubleAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadString_Test(Type protocolType)
+ {
+ var expected = nameof(String);
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteStringAsync(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadStringAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ [DataTestMethod]
+ [DataRow(typeof(TBinaryProtocol))]
+ [DataRow(typeof(TCompactProtocol))]
+ [DataRow(typeof(TJsonProtocol))]
+ public async Task WriteReadBinary_Test(Type protocolType)
+ {
+ var expected = Encoding.UTF8.GetBytes(nameof(String));
+
+ try
+ {
+ var tuple = GetProtocolInstance(protocolType);
+ using (var stream = tuple.Item1)
+ {
+ var protocol = tuple.Item2;
+
+ await protocol.WriteBinaryAsync(expected);
+
+ stream?.Seek(0, SeekOrigin.Begin);
+
+ var actual = await protocol.ReadBinaryAsync();
+
+ var result = _compareLogic.Compare(expected, actual);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e);
+ }
+ }
+
+ private static Tuple<Stream, TProtocol> GetProtocolInstance(Type protocolType)
+ {
+ var memoryStream = new MemoryStream();
+ var streamClientTransport = new TStreamTransport(memoryStream, memoryStream);
+ var protocol = (TProtocol) Activator.CreateInstance(protocolType, streamClientTransport);
+ return new Tuple<Stream, TProtocol>(memoryStream, protocol);
+ }
+ }
+}
diff --git a/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
new file mode 100644
index 0000000..381d8aa
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
@@ -0,0 +1,48 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <!--
+ 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.
+ -->
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ <AssemblyName>Thrift.IntegrationTests</AssemblyName>
+ <PackageId>Thrift.IntegrationTests</PackageId>
+ <OutputType>Exe</OutputType>
+ <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
+ <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="CompareNETObjects" Version="4.58.0" />
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
+ <PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
+ <PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
+ <PackageReference Include="System.ServiceModel.Primitives" Version="4.5.3" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Thrift\Thrift.csproj" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+ </ItemGroup>
+
+</Project>
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/CassandraTest.thrift b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/CassandraTest.thrift
new file mode 100644
index 0000000..26cb380
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/CassandraTest.thrift
@@ -0,0 +1,705 @@
+#!/usr/local/bin/thrift --java --php --py
+# 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.
+
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# *** PLEASE REMEMBER TO EDIT THE VERSION CONSTANT WHEN MAKING CHANGES ***
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+#
+# Interface definition for Cassandra Service
+#
+
+namespace netstd Apache.Cassandra.Test
+
+# Thrift.rb has a bug where top-level modules that include modules
+# with the same name are not properly referenced, so we can't do
+# Cassandra::Cassandra::Client.
+namespace rb CassandraThrift
+
+# The API version (NOT the product version), composed as a dot delimited
+# string with major, minor, and patch level components.
+#
+# - Major: Incremented for backward incompatible changes. An example would
+# be changes to the number or disposition of method arguments.
+# - Minor: Incremented for backward compatible changes. An example would
+# be the addition of a new (optional) method.
+# - Patch: Incremented for bug fixes. The patch level should be increased
+# for every edit that doesn't result in a change to major/minor.
+#
+# See the Semantic Versioning Specification (SemVer) http://semver.org.
+const string VERSION = "19.24.0"
+
+
+#
+# data structures
+#
+
+/** Basic unit of data within a ColumnFamily.
+ * @param name, the name by which this column is set and retrieved. Maximum 64KB long.
+ * @param value. The data associated with the name. Maximum 2GB long, but in practice you should limit it to small numbers of MB (since Thrift must read the full value into memory to operate on it).
+ * @param timestamp. The timestamp is used for conflict detection/resolution when two columns with same name need to be compared.
+ * @param ttl. An optional, positive delay (in seconds) after which the column will be automatically deleted.
+ */
+struct Column {
+ 1: required binary name,
+ 2: optional binary value,
+ 3: optional i64 timestamp,
+ 4: optional i32 ttl,
+}
+
+/** A named list of columns.
+ * @param name. see Column.name.
+ * @param columns. A collection of standard Columns. The columns within a super column are defined in an adhoc manner.
+ * Columns within a super column do not have to have matching structures (similarly named child columns).
+ */
+struct SuperColumn {
+ 1: required binary name,
+ 2: required list<Column> columns,
+}
+
+struct CounterColumn {
+ 1: required binary name,
+ 2: required i64 value
+}
+
+struct CounterSuperColumn {
+ 1: required binary name,
+ 2: required list<CounterColumn> columns
+}
+
+/**
+ Methods for fetching rows/records from Cassandra will return either a single instance of ColumnOrSuperColumn or a list
+ of ColumnOrSuperColumns (get_slice()). If you're looking up a SuperColumn (or list of SuperColumns) then the resulting
+ instances of ColumnOrSuperColumn will have the requested SuperColumn in the attribute super_column. For queries resulting
+ in Columns, those values will be in the attribute column. This change was made between 0.3 and 0.4 to standardize on
+ single query methods that may return either a SuperColumn or Column.
+
+ If the query was on a counter column family, you will either get a counter_column (instead of a column) or a
+ counter_super_column (instead of a super_column)
+
+ @param column. The Column returned by get() or get_slice().
+ @param super_column. The SuperColumn returned by get() or get_slice().
+ @param counter_column. The Counterolumn returned by get() or get_slice().
+ @param counter_super_column. The CounterSuperColumn returned by get() or get_slice().
+ */
+struct ColumnOrSuperColumn {
+ 1: optional Column column,
+ 2: optional SuperColumn super_column,
+ 3: optional CounterColumn counter_column,
+ 4: optional CounterSuperColumn counter_super_column
+}
+
+
+#
+# Exceptions
+# (note that internal server errors will raise a TApplicationException, courtesy of Thrift)
+#
+
+/** A specific column was requested that does not exist. */
+exception NotFoundException {
+}
+
+/** Invalid request could mean keyspace or column family does not exist, required parameters are missing, or a parameter is malformed.
+ why contains an associated error message.
+*/
+exception InvalidRequestException {
+ 1: required string why
+}
+
+/** Not all the replicas required could be created and/or read. */
+exception UnavailableException {
+}
+
+/** RPC timeout was exceeded. either a node failed mid-operation, or load was too high, or the requested op was too large. */
+exception TimedOutException {
+}
+
+/** invalid authentication request (invalid keyspace, user does not exist, or credentials invalid) */
+exception AuthenticationException {
+ 1: required string why
+}
+
+/** invalid authorization request (user does not have access to keyspace) */
+exception AuthorizationException {
+ 1: required string why
+}
+
+/** schemas are not in agreement across all nodes */
+exception SchemaDisagreementException {
+}
+
+
+#
+# service api
+#
+/**
+ * The ConsistencyLevel is an enum that controls both read and write
+ * behavior based on the ReplicationFactor of the keyspace. The
+ * different consistency levels have different meanings, depending on
+ * if you're doing a write or read operation.
+ *
+ * If W + R > ReplicationFactor, where W is the number of nodes to
+ * block for on write, and R the number to block for on reads, you
+ * will have strongly consistent behavior; that is, readers will
+ * always see the most recent write. Of these, the most interesting is
+ * to do QUORUM reads and writes, which gives you consistency while
+ * still allowing availability in the face of node failures up to half
+ * of <ReplicationFactor>. Of course if latency is more important than
+ * consistency then you can use lower values for either or both.
+ *
+ * Some ConsistencyLevels (ONE, TWO, THREE) refer to a specific number
+ * of replicas rather than a logical concept that adjusts
+ * automatically with the replication factor. Of these, only ONE is
+ * commonly used; TWO and (even more rarely) THREE are only useful
+ * when you care more about guaranteeing a certain level of
+ * durability, than consistency.
+ *
+ * Write consistency levels make the following guarantees before reporting success to the client:
+ * ANY Ensure that the write has been written once somewhere, including possibly being hinted in a non-target node.
+ * ONE Ensure that the write has been written to at least 1 node's commit log and memory table
+ * TWO Ensure that the write has been written to at least 2 node's commit log and memory table
+ * THREE Ensure that the write has been written to at least 3 node's commit log and memory table
+ * QUORUM Ensure that the write has been written to <ReplicationFactor> / 2 + 1 nodes
+ * LOCAL_QUORUM Ensure that the write has been written to <ReplicationFactor> / 2 + 1 nodes, within the local datacenter (requires NetworkTopologyStrategy)
+ * EACH_QUORUM Ensure that the write has been written to <ReplicationFactor> / 2 + 1 nodes in each datacenter (requires NetworkTopologyStrategy)
+ * ALL Ensure that the write is written to <code><ReplicationFactor></code> nodes before responding to the client.
+ *
+ * Read consistency levels make the following guarantees before returning successful results to the client:
+ * ANY Not supported. You probably want ONE instead.
+ * ONE Returns the record obtained from a single replica.
+ * TWO Returns the record with the most recent timestamp once two replicas have replied.
+ * THREE Returns the record with the most recent timestamp once three replicas have replied.
+ * QUORUM Returns the record with the most recent timestamp once a majority of replicas have replied.
+ * LOCAL_QUORUM Returns the record with the most recent timestamp once a majority of replicas within the local datacenter have replied.
+ * EACH_QUORUM Returns the record with the most recent timestamp once a majority of replicas within each datacenter have replied.
+ * ALL Returns the record with the most recent timestamp once all replicas have replied (implies no replica may be down)..
+*/
+enum ConsistencyLevel {
+ ONE = 1,
+ QUORUM = 2,
+ LOCAL_QUORUM = 3,
+ EACH_QUORUM = 4,
+ ALL = 5,
+ ANY = 6,
+ TWO = 7,
+ THREE = 8,
+}
+
+/**
+ ColumnParent is used when selecting groups of columns from the same ColumnFamily. In directory structure terms, imagine
+ ColumnParent as ColumnPath + '/../'.
+
+ See also <a href="cassandra.html#Struct_ColumnPath">ColumnPath</a>
+ */
+struct ColumnParent {
+ 3: required string column_family,
+ 4: optional binary super_column,
+}
+
+/** The ColumnPath is the path to a single column in Cassandra. It might make sense to think of ColumnPath and
+ * ColumnParent in terms of a directory structure.
+ *
+ * ColumnPath is used to looking up a single column.
+ *
+ * @param column_family. The name of the CF of the column being looked up.
+ * @param super_column. The super column name.
+ * @param column. The column name.
+ */
+struct ColumnPath {
+ 3: required string column_family,
+ 4: optional binary super_column,
+ 5: optional binary column,
+}
+
+/**
+ A slice range is a structure that stores basic range, ordering and limit information for a query that will return
+ multiple columns. It could be thought of as Cassandra's version of LIMIT and ORDER BY
+
+ @param start. The column name to start the slice with. This attribute is not required, though there is no default value,
+ and can be safely set to '', i.e., an empty byte array, to start with the first column name. Otherwise, it
+ must a valid value under the rules of the Comparator defined for the given ColumnFamily.
+ @param finish. The column name to stop the slice at. This attribute is not required, though there is no default value,
+ and can be safely set to an empty byte array to not stop until 'count' results are seen. Otherwise, it
+ must also be a valid value to the ColumnFamily Comparator.
+ @param reversed. Whether the results should be ordered in reversed order. Similar to ORDER BY blah DESC in SQL.
+ @param count. How many columns to return. Similar to LIMIT in SQL. May be arbitrarily large, but Thrift will
+ materialize the whole result into memory before returning it to the client, so be aware that you may
+ be better served by iterating through slices by passing the last value of one call in as the 'start'
+ of the next instead of increasing 'count' arbitrarily large.
+ */
+struct SliceRange {
+ 1: required binary start,
+ 2: required binary finish,
+ 3: required bool reversed=0,
+ 4: required i32 count=100,
+}
+
+/**
+ A SlicePredicate is similar to a mathematic predicate (see http://en.wikipedia.org/wiki/Predicate_(mathematical_logic)),
+ which is described as "a property that the elements of a set have in common."
+
+ SlicePredicate's in Cassandra are described with either a list of column_names or a SliceRange. If column_names is
+ specified, slice_range is ignored.
+
+ @param column_name. A list of column names to retrieve. This can be used similar to Memcached's "multi-get" feature
+ to fetch N known column names. For instance, if you know you wish to fetch columns 'Joe', 'Jack',
+ and 'Jim' you can pass those column names as a list to fetch all three at once.
+ @param slice_range. A SliceRange describing how to range, order, and/or limit the slice.
+ */
+struct SlicePredicate {
+ 1: optional list<binary> column_names,
+ 2: optional SliceRange slice_range,
+}
+
+enum IndexOperator {
+ EQ,
+ GTE,
+ GT,
+ LTE,
+ LT
+}
+
+struct IndexExpression {
+ 1: required binary column_name,
+ 2: required IndexOperator op,
+ 3: required binary value,
+}
+
+struct IndexClause {
+ 1: required list<IndexExpression> expressions
+ 2: required binary start_key,
+ 3: required i32 count=100,
+}
+
+/**
+The semantics of start keys and tokens are slightly different.
+Keys are start-inclusive; tokens are start-exclusive. Token
+ranges may also wrap -- that is, the end token may be less
+than the start one. Thus, a range from keyX to keyX is a
+one-element range, but a range from tokenY to tokenY is the
+full ring.
+*/
+struct KeyRange {
+ 1: optional binary start_key,
+ 2: optional binary end_key,
+ 3: optional string start_token,
+ 4: optional string end_token,
+ 5: required i32 count=100
+}
+
+/**
+ A KeySlice is key followed by the data it maps to. A collection of KeySlice is returned by the get_range_slice operation.
+
+ @param key. a row key
+ @param columns. List of data represented by the key. Typically, the list is pared down to only the columns specified by
+ a SlicePredicate.
+ */
+struct KeySlice {
+ 1: required binary key,
+ 2: required list<ColumnOrSuperColumn> columns,
+}
+
+struct KeyCount {
+ 1: required binary key,
+ 2: required i32 count
+}
+
+/**
+ * Note that the timestamp is only optional in case of counter deletion.
+ */
+struct Deletion {
+ 1: optional i64 timestamp,
+ 2: optional binary super_column,
+ 3: optional SlicePredicate predicate,
+}
+
+/**
+ A Mutation is either an insert (represented by filling column_or_supercolumn) or a deletion (represented by filling the deletion attribute).
+ @param column_or_supercolumn. An insert to a column or supercolumn (possibly counter column or supercolumn)
+ @param deletion. A deletion of a column or supercolumn
+*/
+struct Mutation {
+ 1: optional ColumnOrSuperColumn column_or_supercolumn,
+ 2: optional Deletion deletion,
+}
+
+struct EndpointDetails {
+ 1: string host,
+ 2: string datacenter,
+ 3: optional string rack
+}
+
+/**
+ A TokenRange describes part of the Cassandra ring, it is a mapping from a range to
+ endpoints responsible for that range.
+ @param start_token The first token in the range
+ @param end_token The last token in the range
+ @param endpoints The endpoints responsible for the range (listed by their configured listen_address)
+ @param rpc_endpoints The endpoints responsible for the range (listed by their configured rpc_address)
+*/
+struct TokenRange {
+ 1: required string start_token,
+ 2: required string end_token,
+ 3: required list<string> endpoints,
+ 4: optional list<string> rpc_endpoints
+ 5: optional list<EndpointDetails> endpoint_details,
+}
+
+/**
+ Authentication requests can contain any data, dependent on the IAuthenticator used
+*/
+struct AuthenticationRequest {
+ 1: required map<string, string> credentials
+}
+
+enum IndexType {
+ KEYS,
+ CUSTOM
+}
+
+/* describes a column in a column family. */
+struct ColumnDef {
+ 1: required binary name,
+ 2: required string validation_class,
+ 3: optional IndexType index_type,
+ 4: optional string index_name,
+ 5: optional map<string,string> index_options
+}
+
+
+/* describes a column family. */
+struct CfDef {
+ 1: required string keyspace,
+ 2: required string name,
+ 3: optional string column_type="Standard",
+ 5: optional string comparator_type="BytesType",
+ 6: optional string subcomparator_type,
+ 8: optional string comment,
+ 12: optional double read_repair_chance=1.0,
+ 13: optional list<ColumnDef> column_metadata,
+ 14: optional i32 gc_grace_seconds,
+ 15: optional string default_validation_class,
+ 16: optional i32 id,
+ 17: optional i32 min_compaction_threshold,
+ 18: optional i32 max_compaction_threshold,
+ 24: optional bool replicate_on_write,
+ 25: optional double merge_shards_chance,
+ 26: optional string key_validation_class,
+ 28: optional binary key_alias,
+ 29: optional string compaction_strategy,
+ 30: optional map<string,string> compaction_strategy_options,
+ 32: optional map<string,string> compression_options,
+ 33: optional double bloom_filter_fp_chance,
+}
+
+/* describes a keyspace. */
+struct KsDef {
+ 1: required string name,
+ 2: required string strategy_class,
+ 3: optional map<string,string> strategy_options,
+
+ /** @deprecated */
+ 4: optional i32 replication_factor,
+
+ 5: required list<CfDef> cf_defs,
+ 6: optional bool durable_writes=1,
+}
+
+/** CQL query compression */
+enum Compression {
+ GZIP = 1,
+ NONE = 2
+}
+
+enum CqlResultType {
+ ROWS = 1,
+ VOID = 2,
+ INT = 3
+}
+
+/** Row returned from a CQL query */
+struct CqlRow {
+ 1: required binary key,
+ 2: required list<Column> columns
+}
+
+struct CqlMetadata {
+ 1: required map<binary,string> name_types,
+ 2: required map<binary,string> value_types,
+ 3: required string default_name_type,
+ 4: required string default_value_type
+}
+
+struct CqlResult {
+ 1: required CqlResultType type,
+ 2: optional list<CqlRow> rows,
+ 3: optional i32 num,
+ 4: optional CqlMetadata schema
+}
+
+struct CqlPreparedResult {
+ 1: required i32 itemId,
+ 2: required i32 count
+}
+
+
+service Cassandra {
+ # auth methods
+ void login(1: required AuthenticationRequest auth_request) throws (1:AuthenticationException authnx, 2:AuthorizationException authzx),
+
+ # set keyspace
+ void set_keyspace(1: required string keyspace) throws (1:InvalidRequestException ire),
+
+ # retrieval methods
+
+ /**
+ Get the Column or SuperColumn at the given column_path. If no value is present, NotFoundException is thrown. (This is
+ the only method that can throw an exception under non-failure conditions.)
+ */
+ ColumnOrSuperColumn get(1:required binary key,
+ 2:required ColumnPath column_path,
+ 3:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:NotFoundException nfe, 3:UnavailableException ue, 4:TimedOutException te),
+
+ /**
+ Get the group of columns contained by column_parent (either a ColumnFamily name or a ColumnFamily/SuperColumn name
+ pair) specified by the given SlicePredicate. If no matching values are found, an empty list is returned.
+ */
+ list<ColumnOrSuperColumn> get_slice(1:required binary key,
+ 2:required ColumnParent column_parent,
+ 3:required SlicePredicate predicate,
+ 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+ /**
+ returns the number of columns matching <code>predicate</code> for a particular <code>key</code>,
+ <code>ColumnFamily</code> and optionally <code>SuperColumn</code>.
+ */
+ i32 get_count(1:required binary key,
+ 2:required ColumnParent column_parent,
+ 3:required SlicePredicate predicate,
+ 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+ /**
+ Performs a get_slice for column_parent and predicate for the given keys in parallel.
+ */
+ map<binary,list<ColumnOrSuperColumn>> multiget_slice(1:required list<binary> keys,
+ 2:required ColumnParent column_parent,
+ 3:required SlicePredicate predicate,
+ 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+ /**
+ Perform a get_count in parallel on the given list<binary> keys. The return value maps keys to the count found.
+ */
+ map<binary, i32> multiget_count(1:required list<binary> keys,
+ 2:required ColumnParent column_parent,
+ 3:required SlicePredicate predicate,
+ 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+ /**
+ returns a subset of columns for a contiguous range of keys.
+ */
+ list<KeySlice> get_range_slices(1:required ColumnParent column_parent,
+ 2:required SlicePredicate predicate,
+ 3:required KeyRange range,
+ 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+ /** Returns the subset of columns specified in SlicePredicate for the rows matching the IndexClause */
+ list<KeySlice> get_indexed_slices(1:required ColumnParent column_parent,
+ 2:required IndexClause index_clause,
+ 3:required SlicePredicate column_predicate,
+ 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+ # modification methods
+
+ /**
+ * Insert a Column at the given column_parent.column_family and optional column_parent.super_column.
+ */
+ void insert(1:required binary key,
+ 2:required ColumnParent column_parent,
+ 3:required Column column,
+ 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+ /**
+ * Increment or decrement a counter.
+ */
+ void add(1:required binary key,
+ 2:required ColumnParent column_parent,
+ 3:required CounterColumn column,
+ 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+ /**
+ Remove data from the row specified by key at the granularity specified by column_path, and the given timestamp. Note
+ that all the values in column_path besides column_path.column_family are truly optional: you can remove the entire
+ row by just specifying the ColumnFamily, or you can remove a SuperColumn or a single Column by specifying those levels too.
+ */
+ void remove(1:required binary key,
+ 2:required ColumnPath column_path,
+ 3:required i64 timestamp,
+ 4:ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+ /**
+ * Remove a counter at the specified location.
+ * Note that counters have limited support for deletes: if you remove a counter, you must wait to issue any following update
+ * until the delete has reached all the nodes and all of them have been fully compacted.
+ */
+ void remove_counter(1:required binary key,
+ 2:required ColumnPath path,
+ 3:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+
+ /**
+ Mutate many columns or super columns for many row keys. See also: Mutation.
+
+ mutation_map maps key to column family to a list of Mutation objects to take place at that scope.
+ **/
+ void batch_mutate(1:required map<binary, map<string, list<Mutation>>> mutation_map,
+ 2:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE)
+ throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+ /**
+ Truncate will mark and entire column family as deleted.
+ From the user's perspective a successful call to truncate will result complete data deletion from cfname.
+ Internally, however, disk space will not be immediatily released, as with all deletes in cassandra, this one
+ only marks the data as deleted.
+ The operation succeeds only if all hosts in the cluster at available and will throw an UnavailableException if
+ some hosts are down.
+ */
+ void truncate(1:required string cfname)
+ throws (1: InvalidRequestException ire, 2: UnavailableException ue, 3: TimedOutException te),
+
+
+
+ // Meta-APIs -- APIs to get information about the node or cluster,
+ // rather than user data. The nodeprobe program provides usage examples.
+
+ /**
+ * for each schema version present in the cluster, returns a list of nodes at that version.
+ * hosts that do not respond will be under the key DatabaseDescriptor.INITIAL_VERSION.
+ * the cluster is all on the same version if the size of the map is 1.
+ */
+ map<string, list<string>> describe_schema_versions()
+ throws (1: InvalidRequestException ire),
+
+ /** list the defined keyspaces in this cluster */
+ list<KsDef> describe_keyspaces()
+ throws (1:InvalidRequestException ire),
+
+ /** get the cluster name */
+ string describe_cluster_name(),
+
+ /** get the thrift api version */
+ string describe_version(),
+
+ /** get the token ring: a map of ranges to host addresses,
+ represented as a set of TokenRange instead of a map from range
+ to list of endpoints, because you can't use Thrift structs as
+ map keys:
+ https://issues.apache.org/jira/browse/THRIFT-162
+
+ for the same reason, we can't return a set here, even though
+ order is neither important nor predictable. */
+ list<TokenRange> describe_ring(1:required string keyspace)
+ throws (1:InvalidRequestException ire),
+
+ /** returns the partitioner used by this cluster */
+ string describe_partitioner(),
+
+ /** returns the snitch used by this cluster */
+ string describe_snitch(),
+
+ /** describe specified keyspace */
+ KsDef describe_keyspace(1:required string keyspace)
+ throws (1:NotFoundException nfe, 2:InvalidRequestException ire),
+
+ /** experimental API for hadoop/parallel query support.
+ may change violently and without warning.
+
+ returns list of token strings such that first subrange is (list[0], list[1]],
+ next is (list[1], list[2]], etc. */
+ list<string> describe_splits(1:required string cfName,
+ 2:required string start_token,
+ 3:required string end_token,
+ 4:required i32 keys_per_split)
+ throws (1:InvalidRequestException ire),
+
+ /** adds a column family. returns the new schema id. */
+ string system_add_column_family(1:required CfDef cf_def)
+ throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde),
+
+ /** drops a column family. returns the new schema id. */
+ string system_drop_column_family(1:required string column_family)
+ throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde),
+
+ /** adds a keyspace and any column families that are part of it. returns the new schema id. */
+ string system_add_keyspace(1:required KsDef ks_def)
+ throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde),
+
+ /** drops a keyspace and any column families that are part of it. returns the new schema id. */
+ string system_drop_keyspace(1:required string keyspace)
+ throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde),
+
+ /** updates properties of a keyspace. returns the new schema id. */
+ string system_update_keyspace(1:required KsDef ks_def)
+ throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde),
+
+ /** updates properties of a column family. returns the new schema id. */
+ string system_update_column_family(1:required CfDef cf_def)
+ throws (1:InvalidRequestException ire, 2:SchemaDisagreementException sde),
+
+ /**
+ * Executes a CQL (Cassandra Query Language) statement and returns a
+ * CqlResult containing the results.
+ */
+ CqlResult execute_cql_query(1:required binary query, 2:required Compression compression)
+ throws (1:InvalidRequestException ire,
+ 2:UnavailableException ue,
+ 3:TimedOutException te,
+ 4:SchemaDisagreementException sde)
+
+
+ /**
+ * Prepare a CQL (Cassandra Query Language) statement by compiling and returning
+ * - the type of CQL statement
+ * - an id token of the compiled CQL stored on the server side.
+ * - a count of the discovered bound markers in the statement
+ */
+ CqlPreparedResult prepare_cql_query(1:required binary query, 2:required Compression compression)
+ throws (1:InvalidRequestException ire)
+
+
+ /**
+ * Executes a prepared CQL (Cassandra Query Language) statement by passing an id token and a list of variables
+ * to bind and returns a CqlResult containing the results.
+ */
+ CqlResult execute_prepared_cql_query(1:required i32 itemId, 2:required list<string> values)
+ throws (1:InvalidRequestException ire,
+ 2:UnavailableException ue,
+ 3:TimedOutException te,
+ 4:SchemaDisagreementException sde)
+
+
+}
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Properties/AssemblyInfo.cs b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..0bb460f
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// 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.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("d0d3706b-fed5-4cf5-b984-04f448de9d7b")]
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
new file mode 100644
index 0000000..58f61a2
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
@@ -0,0 +1,54 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <!--
+ 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.
+ -->
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ <AssemblyName>Thrift.PublicInterfaces.Compile.Tests</AssemblyName>
+ <PackageId>Thrift.PublicInterfaces.Compile.Tests</PackageId>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../../Thrift/Thrift.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="System.ServiceModel.Primitives" Version="4.5.3" />
+ </ItemGroup>
+
+ <Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
+ <Exec Condition="'$(OS)' == 'Windows_NT'" Command="where thrift" ConsoleToMSBuild="true">
+ <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" />
+ </Exec>
+ <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./CassandraTest.thrift" />
+ <Exec Condition="Exists('thrift')" Command="thrift -gen netstd:wcf,union,serial -r ./CassandraTest.thrift" />
+ <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -gen netstd:wcf,union,serial -r ./CassandraTest.thrift" />
+ <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./../../../../test/ThriftTest.thrift" />
+ <Exec Condition="Exists('thrift')" Command="thrift -gen netstd:wcf,union,serial -r ./../../../../test/ThriftTest.thrift" />
+ <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -gen netstd:wcf,union,serial -r ./../../../../test/ThriftTest.thrift" />
+ <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./../../../../contrib/fb303/if/fb303.thrift" />
+ <Exec Condition="Exists('thrift')" Command="thrift -gen netstd:wcf,union,serial -r ./../../../../contrib/fb303/if/fb303.thrift" />
+ <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -gen netstd:wcf,union,serial -r ./../../../../contrib/fb303/if/fb303.thrift" />
+ </Target>
+
+</Project>
diff --git a/lib/netstd/Tests/Thrift.Tests/Collections/TCollectionsTests.cs b/lib/netstd/Tests/Thrift.Tests/Collections/TCollectionsTests.cs
new file mode 100644
index 0000000..1be99b4
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.Tests/Collections/TCollectionsTests.cs
@@ -0,0 +1,83 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Collections;
+
+namespace Thrift.Tests.Collections
+{
+ // ReSharper disable once InconsistentNaming
+ [TestClass]
+ public class TCollectionsTests
+ {
+ //TODO: Add tests for IEnumerable with objects and primitive values inside
+
+ [TestMethod]
+ public void TCollection_Equals_Primitive_Test()
+ {
+ var collection1 = new List<int> {1,2,3};
+ var collection2 = new List<int> {1,2,3};
+
+ var result = TCollections.Equals(collection1, collection2);
+
+ Assert.IsTrue(result);
+ }
+
+ [TestMethod]
+ public void TCollection_Equals_Primitive_Different_Test()
+ {
+ var collection1 = new List<int> { 1, 2, 3 };
+ var collection2 = new List<int> { 1, 2 };
+
+ var result = TCollections.Equals(collection1, collection2);
+
+ Assert.IsFalse(result);
+ }
+
+ [TestMethod]
+ public void TCollection_Equals_Objects_Test()
+ {
+ var collection1 = new List<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } };
+ var collection2 = new List<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } };
+
+ var result = TCollections.Equals(collection1, collection2);
+
+ // references to different collections
+ Assert.IsFalse(result);
+ }
+
+ [TestMethod]
+ public void TCollection_Equals_OneAndTheSameObject_Test()
+ {
+ var collection1 = new List<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } };
+ var collection2 = collection1;
+
+ var result = TCollections.Equals(collection1, collection2);
+
+ // references to one and the same collection
+ Assert.IsTrue(result);
+ }
+
+ private class ExampleClass
+ {
+ public int X { get; set; }
+ }
+ }
+}
diff --git a/lib/netstd/Tests/Thrift.Tests/Collections/THashSetTests.cs b/lib/netstd/Tests/Thrift.Tests/Collections/THashSetTests.cs
new file mode 100644
index 0000000..8de573e
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.Tests/Collections/THashSetTests.cs
@@ -0,0 +1,71 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Collections;
+
+namespace Thrift.Tests.Collections
+{
+ // ReSharper disable once InconsistentNaming
+ [TestClass]
+ public class THashSetTests
+ {
+ [TestMethod]
+ public void THashSet_Equals_Primitive_Test()
+ {
+ const int value = 1;
+
+ var hashSet = new THashSet<int> {value};
+
+ Assert.IsTrue(hashSet.Contains(value));
+
+ hashSet.Remove(value);
+
+ Assert.IsTrue(hashSet.Count == 0);
+
+ hashSet.Add(value);
+
+ Assert.IsTrue(hashSet.Contains(value));
+
+ hashSet.Clear();
+
+ Assert.IsTrue(hashSet.Count == 0);
+
+ var newArr = new int[1];
+ hashSet.Add(value);
+ hashSet.CopyTo(newArr, 0);
+
+ Assert.IsTrue(newArr.Contains(value));
+
+ var en = hashSet.GetEnumerator();
+ en.MoveNext();
+
+ Assert.IsTrue((int)en.Current == value);
+
+ using (var ien = ((IEnumerable<int>)hashSet).GetEnumerator())
+ {
+ ien.MoveNext();
+
+ Assert.IsTrue(ien.Current == value);
+ }
+ }
+ }
+}
diff --git a/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs b/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs
new file mode 100644
index 0000000..6d39151
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs
@@ -0,0 +1,172 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Protocol;
+using Thrift.Protocol.Entities;
+using Thrift.Protocol.Utilities;
+
+namespace Thrift.Tests.Protocols
+{
+ [TestClass]
+ public class TJSONProtocolHelperTests
+ {
+ [TestMethod]
+ public void GetTypeNameForTypeId_Test()
+ {
+ // input/output
+ var sets = new List<Tuple<TType, byte[]>>
+ {
+ new Tuple<TType, byte[]>(TType.Bool, TJSONProtocolConstants.TypeNames.NameBool),
+ new Tuple<TType, byte[]>(TType.Byte, TJSONProtocolConstants.TypeNames.NameByte),
+ new Tuple<TType, byte[]>(TType.I16, TJSONProtocolConstants.TypeNames.NameI16),
+ new Tuple<TType, byte[]>(TType.I32, TJSONProtocolConstants.TypeNames.NameI32),
+ new Tuple<TType, byte[]>(TType.I64, TJSONProtocolConstants.TypeNames.NameI64),
+ new Tuple<TType, byte[]>(TType.Double, TJSONProtocolConstants.TypeNames.NameDouble),
+ new Tuple<TType, byte[]>(TType.String, TJSONProtocolConstants.TypeNames.NameString),
+ new Tuple<TType, byte[]>(TType.Struct, TJSONProtocolConstants.TypeNames.NameStruct),
+ new Tuple<TType, byte[]>(TType.Map, TJSONProtocolConstants.TypeNames.NameMap),
+ new Tuple<TType, byte[]>(TType.Set, TJSONProtocolConstants.TypeNames.NameSet),
+ new Tuple<TType, byte[]>(TType.List, TJSONProtocolConstants.TypeNames.NameList),
+ };
+
+ foreach (var t in sets)
+ {
+ Assert.IsTrue(TJSONProtocolHelper.GetTypeNameForTypeId(t.Item1) == t.Item2, $"Wrong mapping of TypeName {t.Item2} to TType: {t.Item1}");
+ }
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void GetTypeNameForTypeId_TStop_Test()
+ {
+ TJSONProtocolHelper.GetTypeNameForTypeId(TType.Stop);
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void GetTypeNameForTypeId_NonExistingTType_Test()
+ {
+ TJSONProtocolHelper.GetTypeNameForTypeId((TType)100);
+ }
+
+ [TestMethod]
+ public void GetTypeIdForTypeName_Test()
+ {
+ // input/output
+ var sets = new List<Tuple<TType, byte[]>>
+ {
+ new Tuple<TType, byte[]>(TType.Bool, TJSONProtocolConstants.TypeNames.NameBool),
+ new Tuple<TType, byte[]>(TType.Byte, TJSONProtocolConstants.TypeNames.NameByte),
+ new Tuple<TType, byte[]>(TType.I16, TJSONProtocolConstants.TypeNames.NameI16),
+ new Tuple<TType, byte[]>(TType.I32, TJSONProtocolConstants.TypeNames.NameI32),
+ new Tuple<TType, byte[]>(TType.I64, TJSONProtocolConstants.TypeNames.NameI64),
+ new Tuple<TType, byte[]>(TType.Double, TJSONProtocolConstants.TypeNames.NameDouble),
+ new Tuple<TType, byte[]>(TType.String, TJSONProtocolConstants.TypeNames.NameString),
+ new Tuple<TType, byte[]>(TType.Struct, TJSONProtocolConstants.TypeNames.NameStruct),
+ new Tuple<TType, byte[]>(TType.Map, TJSONProtocolConstants.TypeNames.NameMap),
+ new Tuple<TType, byte[]>(TType.Set, TJSONProtocolConstants.TypeNames.NameSet),
+ new Tuple<TType, byte[]>(TType.List, TJSONProtocolConstants.TypeNames.NameList),
+ };
+
+ foreach (var t in sets)
+ {
+ Assert.IsTrue(TJSONProtocolHelper.GetTypeIdForTypeName(t.Item2) == t.Item1, $"Wrong mapping of TypeName {t.Item2} to TType: {t.Item1}");
+ }
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void GetTypeIdForTypeName_TStopTypeName_Test()
+ {
+ TJSONProtocolHelper.GetTypeIdForTypeName(new []{(byte)TType.Stop, (byte)TType.Stop});
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void GetTypeIdForTypeName_NonExistingTypeName_Test()
+ {
+ TJSONProtocolHelper.GetTypeIdForTypeName(new byte[]{100});
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void GetTypeIdForTypeName_EmptyName_Test()
+ {
+ TJSONProtocolHelper.GetTypeIdForTypeName(new byte[] {});
+ }
+
+ [TestMethod]
+ public void IsJsonNumeric_Test()
+ {
+ // input/output
+ var correctJsonNumeric = "+-.0123456789Ee";
+ var incorrectJsonNumeric = "AaBcDd/*\\";
+
+ var sets = correctJsonNumeric.Select(ch => new Tuple<byte, bool>((byte) ch, true)).ToList();
+ sets.AddRange(incorrectJsonNumeric.Select(ch => new Tuple<byte, bool>((byte) ch, false)));
+
+ foreach (var t in sets)
+ {
+ Assert.IsTrue(TJSONProtocolHelper.IsJsonNumeric(t.Item1) == t.Item2, $"Wrong mapping of Char {t.Item1} to bool: {t.Item2}");
+ }
+ }
+
+ [TestMethod]
+ public void ToHexVal_Test()
+ {
+ // input/output
+ var chars = "0123456789abcdef";
+ var expectedHexValues = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+
+ var sets = chars.Select((ch, i) => new Tuple<char, byte>(ch, expectedHexValues[i])).ToList();
+
+ foreach (var t in sets)
+ {
+ var actualResult = TJSONProtocolHelper.ToHexVal((byte)t.Item1);
+ Assert.IsTrue(actualResult == t.Item2, $"Wrong mapping of char byte {t.Item1} to it expected hex value: {t.Item2}. Actual hex value: {actualResult}");
+ }
+ }
+
+ [TestMethod]
+ [ExpectedException(typeof(TProtocolException))]
+ public void ToHexVal_WrongInputChar_Test()
+ {
+ TJSONProtocolHelper.ToHexVal((byte)'s');
+ }
+
+ [TestMethod]
+ public void ToHexChar_Test()
+ {
+ // input/output
+ var hexValues = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ var expectedChars = "0123456789abcdef";
+
+
+ var sets = hexValues.Select((hv, i) => new Tuple<byte, char>(hv, expectedChars[i])).ToList();
+
+ foreach (var t in sets)
+ {
+ var actualResult = TJSONProtocolHelper.ToHexChar(t.Item1);
+ Assert.IsTrue(actualResult == t.Item2, $"Wrong mapping of hex value {t.Item1} to it expected char: {t.Item2}. Actual hex value: {actualResult}");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs b/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs
new file mode 100644
index 0000000..970ce7e
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs
@@ -0,0 +1,67 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using NSubstitute;
+using Thrift.Protocol;
+using Thrift.Protocol.Entities;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Protocols
+{
+ // ReSharper disable once InconsistentNaming
+ [TestClass]
+ public class TJSONProtocolTests
+ {
+ [TestMethod]
+ public void TJSONProtocol_Can_Create_Instance_Test()
+ {
+ var httpClientTransport = Substitute.For<THttpTransport>(new Uri("http://localhost"), null, null);
+
+ var result = new TJSONProtocolWrapper(httpClientTransport);
+
+ Assert.IsNotNull(result);
+ Assert.IsNotNull(result.WrappedContext);
+ Assert.IsNotNull(result.WrappedReader);
+ Assert.IsNotNull(result.Transport);
+ Assert.IsTrue(result.WrappedRecursionDepth == 0);
+ Assert.IsTrue(result.WrappedRecursionLimit == TProtocol.DefaultRecursionDepth);
+
+ Assert.IsTrue(result.Transport.Equals(httpClientTransport));
+ Assert.IsTrue(result.WrappedContext.GetType().Name.Equals("JSONBaseContext", StringComparison.OrdinalIgnoreCase));
+ Assert.IsTrue(result.WrappedReader.GetType().Name.Equals("LookaheadReader", StringComparison.OrdinalIgnoreCase));
+ }
+
+ private class TJSONProtocolWrapper : TJsonProtocol
+ {
+ public TJSONProtocolWrapper(TTransport trans) : base(trans)
+ {
+ }
+
+ public object WrappedContext => Context;
+ public object WrappedReader => Reader;
+ public int WrappedRecursionDepth => RecursionDepth;
+ public int WrappedRecursionLimit => RecursionLimit;
+ }
+ }
+}
diff --git a/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj
new file mode 100644
index 0000000..434424d
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj
@@ -0,0 +1,36 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <!--
+ 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.
+ -->
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ </PropertyGroup>
+ <ItemGroup>
+ <PackageReference Include="CompareNETObjects" Version="4.58.0" />
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
+ <PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />
+ <PackageReference Include="MSTest.TestFramework" Version="1.4.0" />
+ <PackageReference Include="NSubstitute" Version="4.0.0" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\Thrift\Thrift.csproj" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
+ </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/lib/netstd/Thrift.sln b/lib/netstd/Thrift.sln
new file mode 100644
index 0000000..2952eb0
--- /dev/null
+++ b/lib/netstd/Thrift.sln
@@ -0,0 +1,85 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.12
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{ED5A45B0-07D1-4507-96B7-83FBD3D031CA}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", "Thrift\Thrift.csproj", "{5B501D21-D428-408D-AB5C-32D6F5355294}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.IntegrationTests", "Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj", "{837F4084-AAD7-45F5-BC96-10E05A669DB4}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Tests", "Tests\Thrift.Tests\Thrift.Tests.csproj", "{0790D388-1A3C-4423-8CF2-C97074A8B68B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.PublicInterfaces.Compile.Tests", "Tests\Thrift.PublicInterfaces.Compile.Tests\Thrift.PublicInterfaces.Compile.Tests.csproj", "{A6AE021D-61CB-4D84-A103-0B663C62AE2C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|x64.Build.0 = Debug|Any CPU
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Debug|x86.Build.0 = Debug|Any CPU
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|x64.ActiveCfg = Release|Any CPU
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|x64.Build.0 = Release|Any CPU
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|x86.ActiveCfg = Release|Any CPU
+ {5B501D21-D428-408D-AB5C-32D6F5355294}.Release|x86.Build.0 = Release|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|x64.Build.0 = Debug|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Debug|x86.Build.0 = Debug|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|x64.ActiveCfg = Release|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|x64.Build.0 = Release|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|x86.ActiveCfg = Release|Any CPU
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4}.Release|x86.Build.0 = Release|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|x64.Build.0 = Debug|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Debug|x86.Build.0 = Debug|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|x64.ActiveCfg = Release|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|x64.Build.0 = Release|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|x86.ActiveCfg = Release|Any CPU
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B}.Release|x86.Build.0 = Release|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Debug|x64.Build.0 = Debug|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Debug|x86.Build.0 = Debug|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Release|x64.ActiveCfg = Release|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Release|x64.Build.0 = Release|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Release|x86.ActiveCfg = Release|Any CPU
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {837F4084-AAD7-45F5-BC96-10E05A669DB4} = {ED5A45B0-07D1-4507-96B7-83FBD3D031CA}
+ {0790D388-1A3C-4423-8CF2-C97074A8B68B} = {ED5A45B0-07D1-4507-96B7-83FBD3D031CA}
+ {A6AE021D-61CB-4D84-A103-0B663C62AE2C} = {ED5A45B0-07D1-4507-96B7-83FBD3D031CA}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {FD20BC4A-0109-41D8-8C0C-893E784D7EF9}
+ EndGlobalSection
+EndGlobal
diff --git a/lib/netstd/Thrift/Collections/TCollections.cs b/lib/netstd/Thrift/Collections/TCollections.cs
new file mode 100644
index 0000000..147bfc7
--- /dev/null
+++ b/lib/netstd/Thrift/Collections/TCollections.cs
@@ -0,0 +1,101 @@
+// 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.
+
+using System.Collections;
+
+namespace Thrift.Collections
+{
+ // ReSharper disable once InconsistentNaming
+ public class TCollections
+ {
+ /// <summary>
+ /// This will return true if the two collections are value-wise the same.
+ /// If the collection contains a collection, the collections will be compared using this method.
+ /// </summary>
+ public static bool Equals(IEnumerable first, IEnumerable second)
+ {
+ if (first == null && second == null)
+ {
+ return true;
+ }
+
+ if (first == null || second == null)
+ {
+ return false;
+ }
+
+ var fiter = first.GetEnumerator();
+ var siter = second.GetEnumerator();
+
+ var fnext = fiter.MoveNext();
+ var snext = siter.MoveNext();
+
+ while (fnext && snext)
+ {
+ var fenum = fiter.Current as IEnumerable;
+ var senum = siter.Current as IEnumerable;
+
+ if (fenum != null && senum != null)
+ {
+ if (!Equals(fenum, senum))
+ {
+ return false;
+ }
+ }
+ else if (fenum == null ^ senum == null)
+ {
+ return false;
+ }
+ else if (!Equals(fiter.Current, siter.Current))
+ {
+ return false;
+ }
+
+ fnext = fiter.MoveNext();
+ snext = siter.MoveNext();
+ }
+
+ return fnext == snext;
+ }
+
+ /// <summary>
+ /// This returns a hashcode based on the value of the enumerable.
+ /// </summary>
+ public static int GetHashCode(IEnumerable enumerable)
+ {
+ if (enumerable == null)
+ {
+ return 0;
+ }
+
+ var hashcode = 0;
+
+ foreach (var obj in enumerable)
+ {
+ var enum2 = obj as IEnumerable;
+ var objHash = enum2 == null ? obj.GetHashCode() : GetHashCode(enum2);
+
+ unchecked
+ {
+ hashcode = (hashcode*397) ^ (objHash);
+ }
+ }
+
+ return hashcode;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Collections/THashSet.cs b/lib/netstd/Thrift/Collections/THashSet.cs
new file mode 100644
index 0000000..011f0a0
--- /dev/null
+++ b/lib/netstd/Thrift/Collections/THashSet.cs
@@ -0,0 +1,67 @@
+// 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.
+
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Thrift.Collections
+{
+ // ReSharper disable once InconsistentNaming
+ public class THashSet<T> : ICollection<T>
+ {
+ private readonly HashSet<T> _set = new HashSet<T>();
+
+ public int Count => _set.Count;
+
+ public bool IsReadOnly => false;
+
+ public void Add(T item)
+ {
+ _set.Add(item);
+ }
+
+ public void Clear()
+ {
+ _set.Clear();
+ }
+
+ public bool Contains(T item)
+ {
+ return _set.Contains(item);
+ }
+
+ public void CopyTo(T[] array, int arrayIndex)
+ {
+ _set.CopyTo(array, arrayIndex);
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return _set.GetEnumerator();
+ }
+
+ IEnumerator<T> IEnumerable<T>.GetEnumerator()
+ {
+ return ((IEnumerable<T>) _set).GetEnumerator();
+ }
+
+ public bool Remove(T item)
+ {
+ return _set.Remove(item);
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Processor/ITAsyncProcessor.cs b/lib/netstd/Thrift/Processor/ITAsyncProcessor.cs
new file mode 100644
index 0000000..b8c1bce
--- /dev/null
+++ b/lib/netstd/Thrift/Processor/ITAsyncProcessor.cs
@@ -0,0 +1,28 @@
+// 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.
+
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol;
+
+namespace Thrift.Processor
+{
+ public interface ITAsyncProcessor
+ {
+ Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken cancellationToken = default(CancellationToken));
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Processor/ITProcessorFactory.cs b/lib/netstd/Thrift/Processor/ITProcessorFactory.cs
new file mode 100644
index 0000000..e0fe3d0
--- /dev/null
+++ b/lib/netstd/Thrift/Processor/ITProcessorFactory.cs
@@ -0,0 +1,28 @@
+// 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.
+
+using Thrift.Server;
+using Thrift.Transport;
+
+namespace Thrift.Processor
+{
+ // ReSharper disable once InconsistentNaming
+ public interface ITProcessorFactory
+ {
+ ITAsyncProcessor GetAsyncProcessor(TTransport trans, TServer baseServer = null);
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Processor/TMultiplexedProcessor.cs b/lib/netstd/Thrift/Processor/TMultiplexedProcessor.cs
new file mode 100644
index 0000000..81274be
--- /dev/null
+++ b/lib/netstd/Thrift/Processor/TMultiplexedProcessor.cs
@@ -0,0 +1,143 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol;
+using Thrift.Protocol.Entities;
+
+namespace Thrift.Processor
+{
+ // ReSharper disable once InconsistentNaming
+ public class TMultiplexedProcessor : ITAsyncProcessor
+ {
+ //TODO: Localization
+
+ private readonly Dictionary<string, ITAsyncProcessor> _serviceProcessorMap =
+ new Dictionary<string, ITAsyncProcessor>();
+
+ public async Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot)
+ {
+ return await ProcessAsync(iprot, oprot, CancellationToken.None);
+ }
+
+ public async Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<bool>(cancellationToken);
+ }
+
+ try
+ {
+ var message = await iprot.ReadMessageBeginAsync(cancellationToken);
+
+ if ((message.Type != TMessageType.Call) && (message.Type != TMessageType.Oneway))
+ {
+ await FailAsync(oprot, message, TApplicationException.ExceptionType.InvalidMessageType,
+ "Message exType CALL or ONEWAY expected", cancellationToken);
+ return false;
+ }
+
+ // Extract the service name
+ var index = message.Name.IndexOf(TMultiplexedProtocol.Separator, StringComparison.Ordinal);
+ if (index < 0)
+ {
+ await FailAsync(oprot, message, TApplicationException.ExceptionType.InvalidProtocol,
+ $"Service name not found in message name: {message.Name}. Did you forget to use a TMultiplexProtocol in your client?",
+ cancellationToken);
+ return false;
+ }
+
+ // Create a new TMessage, something that can be consumed by any TProtocol
+ var serviceName = message.Name.Substring(0, index);
+ ITAsyncProcessor actualProcessor;
+ if (!_serviceProcessorMap.TryGetValue(serviceName, out actualProcessor))
+ {
+ await FailAsync(oprot, message, TApplicationException.ExceptionType.InternalError,
+ $"Service name not found: {serviceName}. Did you forget to call RegisterProcessor()?",
+ cancellationToken);
+ return false;
+ }
+
+ // Create a new TMessage, removing the service name
+ var newMessage = new TMessage(
+ message.Name.Substring(serviceName.Length + TMultiplexedProtocol.Separator.Length),
+ message.Type,
+ message.SeqID);
+
+ // Dispatch processing to the stored processor
+ return
+ await
+ actualProcessor.ProcessAsync(new StoredMessageProtocol(iprot, newMessage), oprot,
+ cancellationToken);
+ }
+ catch (IOException)
+ {
+ return false; // similar to all other processors
+ }
+ }
+
+ public void RegisterProcessor(string serviceName, ITAsyncProcessor processor)
+ {
+ if (_serviceProcessorMap.ContainsKey(serviceName))
+ {
+ throw new InvalidOperationException(
+ $"Processor map already contains processor with name: '{serviceName}'");
+ }
+
+ _serviceProcessorMap.Add(serviceName, processor);
+ }
+
+ private async Task FailAsync(TProtocol oprot, TMessage message, TApplicationException.ExceptionType extype,
+ string etxt, CancellationToken cancellationToken)
+ {
+ var appex = new TApplicationException(extype, etxt);
+
+ var newMessage = new TMessage(message.Name, TMessageType.Exception, message.SeqID);
+
+ await oprot.WriteMessageBeginAsync(newMessage, cancellationToken);
+ await appex.WriteAsync(oprot, cancellationToken);
+ await oprot.WriteMessageEndAsync(cancellationToken);
+ await oprot.Transport.FlushAsync(cancellationToken);
+ }
+
+ private class StoredMessageProtocol : TProtocolDecorator
+ {
+ readonly TMessage _msgBegin;
+
+ public StoredMessageProtocol(TProtocol protocol, TMessage messageBegin)
+ : base(protocol)
+ {
+ _msgBegin = messageBegin;
+ }
+
+ public override async Task<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<TMessage>(cancellationToken);
+ }
+
+ return _msgBegin;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Processor/TSingletonProcessorFactory.cs b/lib/netstd/Thrift/Processor/TSingletonProcessorFactory.cs
new file mode 100644
index 0000000..97ecff6
--- /dev/null
+++ b/lib/netstd/Thrift/Processor/TSingletonProcessorFactory.cs
@@ -0,0 +1,38 @@
+// 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.
+
+using Thrift.Server;
+using Thrift.Transport;
+
+namespace Thrift.Processor
+{
+ // ReSharper disable once InconsistentNaming
+ public class TSingletonProcessorFactory : ITProcessorFactory
+ {
+ private readonly ITAsyncProcessor _asyncProcessor;
+
+ public TSingletonProcessorFactory(ITAsyncProcessor asyncProcessor)
+ {
+ _asyncProcessor = asyncProcessor;
+ }
+
+ public ITAsyncProcessor GetAsyncProcessor(TTransport trans, TServer baseServer = null)
+ {
+ return _asyncProcessor;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Properties/AssemblyInfo.cs b/lib/netstd/Thrift/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..e3118ab
--- /dev/null
+++ b/lib/netstd/Thrift/Properties/AssemblyInfo.cs
@@ -0,0 +1,56 @@
+// 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.
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("Thrift")]
+[assembly: AssemblyDescription("C# .NET Core bindings for the Apache Thrift RPC system")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+//@TODO where to put License information?
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a exType in this assembly from
+// COM, set the ComVisible attribute to true on that exType.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("df3f8ef0-e0a3-4c86-a65b-8ec84e016b1d")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.0.1")]
+[assembly: AssemblyFileVersion("1.0.0.1")]
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/Entities/TField.cs b/lib/netstd/Thrift/Protocol/Entities/TField.cs
new file mode 100644
index 0000000..4e29bb5
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Entities/TField.cs
@@ -0,0 +1,37 @@
+// 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.
+
+namespace Thrift.Protocol.Entities
+{
+ // ReSharper disable once InconsistentNaming
+ public struct TField
+ {
+ public TField(string name, TType type, short id)
+ {
+ Name = name;
+ Type = type;
+ ID = id;
+ }
+
+ public string Name { get; set; }
+
+ public TType Type { get; set; }
+
+ // ReSharper disable once InconsistentNaming - do not rename - it used for generation
+ public short ID { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/Entities/TList.cs b/lib/netstd/Thrift/Protocol/Entities/TList.cs
new file mode 100644
index 0000000..f599225
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Entities/TList.cs
@@ -0,0 +1,33 @@
+// 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.
+
+namespace Thrift.Protocol.Entities
+{
+ // ReSharper disable once InconsistentNaming
+ public struct TList
+ {
+ public TList(TType elementType, int count)
+ {
+ ElementType = elementType;
+ Count = count;
+ }
+
+ public TType ElementType { get; set; }
+
+ public int Count { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/Entities/TMap.cs b/lib/netstd/Thrift/Protocol/Entities/TMap.cs
new file mode 100644
index 0000000..1efebe7
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Entities/TMap.cs
@@ -0,0 +1,36 @@
+// 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.
+
+namespace Thrift.Protocol.Entities
+{
+ // ReSharper disable once InconsistentNaming
+ public struct TMap
+ {
+ public TMap(TType keyType, TType valueType, int count)
+ {
+ KeyType = keyType;
+ ValueType = valueType;
+ Count = count;
+ }
+
+ public TType KeyType { get; set; }
+
+ public TType ValueType { get; set; }
+
+ public int Count { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/Entities/TMessage.cs b/lib/netstd/Thrift/Protocol/Entities/TMessage.cs
new file mode 100644
index 0000000..08d741d
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Entities/TMessage.cs
@@ -0,0 +1,37 @@
+// 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.
+
+namespace Thrift.Protocol.Entities
+{
+ // ReSharper disable once InconsistentNaming
+ public struct TMessage
+ {
+ public TMessage(string name, TMessageType type, int seqid)
+ {
+ Name = name;
+ Type = type;
+ SeqID = seqid;
+ }
+
+ public string Name { get; set; }
+
+ public TMessageType Type { get; set; }
+
+ // ReSharper disable once InconsistentNaming - do not rename - it used for generation
+ public int SeqID { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/Entities/TMessageType.cs b/lib/netstd/Thrift/Protocol/Entities/TMessageType.cs
new file mode 100644
index 0000000..24d663e
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Entities/TMessageType.cs
@@ -0,0 +1,28 @@
+// 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.
+
+namespace Thrift.Protocol.Entities
+{
+ // ReSharper disable once InconsistentNaming
+ public enum TMessageType
+ {
+ Call = 1,
+ Reply = 2,
+ Exception = 3,
+ Oneway = 4
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/Entities/TSet.cs b/lib/netstd/Thrift/Protocol/Entities/TSet.cs
new file mode 100644
index 0000000..692d564
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Entities/TSet.cs
@@ -0,0 +1,38 @@
+// 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.
+
+namespace Thrift.Protocol.Entities
+{
+ // ReSharper disable once InconsistentNaming
+ public struct TSet
+ {
+ public TSet(TType elementType, int count)
+ {
+ ElementType = elementType;
+ Count = count;
+ }
+
+ public TSet(TList list)
+ : this(list.ElementType, list.Count)
+ {
+ }
+
+ public TType ElementType { get; set; }
+
+ public int Count { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/Entities/TStruct.cs b/lib/netstd/Thrift/Protocol/Entities/TStruct.cs
new file mode 100644
index 0000000..e04167e
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Entities/TStruct.cs
@@ -0,0 +1,30 @@
+// 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.
+
+namespace Thrift.Protocol.Entities
+{
+ // ReSharper disable once InconsistentNaming
+ public struct TStruct
+ {
+ public TStruct(string name)
+ {
+ Name = name;
+ }
+
+ public string Name { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/Entities/TType.cs b/lib/netstd/Thrift/Protocol/Entities/TType.cs
new file mode 100644
index 0000000..4e922a7
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Entities/TType.cs
@@ -0,0 +1,37 @@
+// 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.
+
+namespace Thrift.Protocol.Entities
+{
+ // ReSharper disable once InconsistentNaming
+ public enum TType : byte
+ {
+ Stop = 0,
+ Void = 1,
+ Bool = 2,
+ Byte = 3,
+ Double = 4,
+ I16 = 6,
+ I32 = 8,
+ I64 = 10,
+ String = 11,
+ Struct = 12,
+ Map = 13,
+ Set = 14,
+ List = 15
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/TBase.cs b/lib/netstd/Thrift/Protocol/TBase.cs
new file mode 100644
index 0000000..b5ef2ae
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/TBase.cs
@@ -0,0 +1,33 @@
+// 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.
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Thrift.Protocol
+{
+ public interface TUnionBase
+ {
+ Task WriteAsync(TProtocol tProtocol, CancellationToken cancellationToken = default(CancellationToken));
+ }
+
+ // ReSharper disable once InconsistentNaming
+ public interface TBase : TUnionBase
+ {
+ Task ReadAsync(TProtocol tProtocol, CancellationToken cancellationToken = default(CancellationToken));
+ }
+}
diff --git a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
new file mode 100644
index 0000000..7a0243a
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
@@ -0,0 +1,613 @@
+// 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.
+
+using System;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol.Entities;
+using Thrift.Transport;
+
+namespace Thrift.Protocol
+{
+ // ReSharper disable once InconsistentNaming
+ public class TBinaryProtocol : TProtocol
+ {
+ //TODO: Unit tests
+ //TODO: Localization
+ //TODO: pragma
+
+ protected const uint VersionMask = 0xffff0000;
+ protected const uint Version1 = 0x80010000;
+
+ protected bool StrictRead;
+ protected bool StrictWrite;
+
+ public TBinaryProtocol(TTransport trans)
+ : this(trans, false, true)
+ {
+ }
+
+ public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
+ : base(trans)
+ {
+ StrictRead = strictRead;
+ StrictWrite = strictWrite;
+ }
+
+ public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ if (StrictWrite)
+ {
+ var version = Version1 | (uint) message.Type;
+ await WriteI32Async((int) version, cancellationToken);
+ await WriteStringAsync(message.Name, cancellationToken);
+ await WriteI32Async(message.SeqID, cancellationToken);
+ }
+ else
+ {
+ await WriteStringAsync(message.Name, cancellationToken);
+ await WriteByteAsync((sbyte) message.Type, cancellationToken);
+ await WriteI32Async(message.SeqID, cancellationToken);
+ }
+ }
+
+ public override async Task WriteMessageEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task WriteStructEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await WriteByteAsync((sbyte) field.Type, cancellationToken);
+ await WriteI16Async(field.ID, cancellationToken);
+ }
+
+ public override async Task WriteFieldEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task WriteFieldStopAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await WriteByteAsync((sbyte) TType.Stop, cancellationToken);
+ }
+
+ public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await WriteByteAsync((sbyte) map.KeyType, cancellationToken);
+ await WriteByteAsync((sbyte) map.ValueType, cancellationToken);
+ await WriteI32Async(map.Count, cancellationToken);
+ }
+
+ public override async Task WriteMapEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await WriteByteAsync((sbyte) list.ElementType, cancellationToken);
+ await WriteI32Async(list.Count, cancellationToken);
+ }
+
+ public override async Task WriteListEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await WriteByteAsync((sbyte) set.ElementType, cancellationToken);
+ await WriteI32Async(set.Count, cancellationToken);
+ }
+
+ public override async Task WriteSetEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await WriteByteAsync(b ? (sbyte) 1 : (sbyte) 0, cancellationToken);
+ }
+
+ protected internal static byte[] CreateWriteByte(sbyte b)
+ {
+ var bout = new byte[1];
+
+ bout[0] = (byte) b;
+
+ return bout;
+ }
+
+ public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ var bout = CreateWriteByte(b);
+ await Trans.WriteAsync(bout, 0, 1, cancellationToken);
+ }
+
+ protected internal static byte[] CreateWriteI16(short s)
+ {
+ var i16Out = new byte[2];
+
+ i16Out[0] = (byte) (0xff & (s >> 8));
+ i16Out[1] = (byte) (0xff & s);
+
+ return i16Out;
+ }
+
+ public override async Task WriteI16Async(short i16, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ var i16Out = CreateWriteI16(i16);
+ await Trans.WriteAsync(i16Out, 0, 2, cancellationToken);
+ }
+
+ protected internal static byte[] CreateWriteI32(int i32)
+ {
+ var i32Out = new byte[4];
+
+ i32Out[0] = (byte) (0xff & (i32 >> 24));
+ i32Out[1] = (byte) (0xff & (i32 >> 16));
+ i32Out[2] = (byte) (0xff & (i32 >> 8));
+ i32Out[3] = (byte) (0xff & i32);
+
+ return i32Out;
+ }
+
+ public override async Task WriteI32Async(int i32, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ var i32Out = CreateWriteI32(i32);
+ await Trans.WriteAsync(i32Out, 0, 4, cancellationToken);
+ }
+
+ protected internal static byte[] CreateWriteI64(long i64)
+ {
+ var i64Out = new byte[8];
+
+ i64Out[0] = (byte) (0xff & (i64 >> 56));
+ i64Out[1] = (byte) (0xff & (i64 >> 48));
+ i64Out[2] = (byte) (0xff & (i64 >> 40));
+ i64Out[3] = (byte) (0xff & (i64 >> 32));
+ i64Out[4] = (byte) (0xff & (i64 >> 24));
+ i64Out[5] = (byte) (0xff & (i64 >> 16));
+ i64Out[6] = (byte) (0xff & (i64 >> 8));
+ i64Out[7] = (byte) (0xff & i64);
+
+ return i64Out;
+ }
+
+ public override async Task WriteI64Async(long i64, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ var i64Out = CreateWriteI64(i64);
+ await Trans.WriteAsync(i64Out, 0, 8, cancellationToken);
+ }
+
+ public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await WriteI64Async(BitConverter.DoubleToInt64Bits(d), cancellationToken);
+ }
+
+ public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await WriteI32Async(bytes.Length, cancellationToken);
+ await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
+ }
+
+ public override async Task<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<TMessage>(cancellationToken);
+ }
+
+ var message = new TMessage();
+ var size = await ReadI32Async(cancellationToken);
+ if (size < 0)
+ {
+ var version = (uint) size & VersionMask;
+ if (version != Version1)
+ {
+ throw new TProtocolException(TProtocolException.BAD_VERSION,
+ $"Bad version in ReadMessageBegin: {version}");
+ }
+ message.Type = (TMessageType) (size & 0x000000ff);
+ message.Name = await ReadStringAsync(cancellationToken);
+ message.SeqID = await ReadI32Async(cancellationToken);
+ }
+ else
+ {
+ if (StrictRead)
+ {
+ throw new TProtocolException(TProtocolException.BAD_VERSION,
+ "Missing version in ReadMessageBegin, old client?");
+ }
+ message.Name = await ReadStringBodyAsync(size, cancellationToken);
+ message.Type = (TMessageType) await ReadByteAsync(cancellationToken);
+ message.SeqID = await ReadI32Async(cancellationToken);
+ }
+ return message;
+ }
+
+ public override async Task ReadMessageEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task<TStruct> ReadStructBeginAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+
+ //TODO: no read from internal transport?
+ return new TStruct();
+ }
+
+ public override async Task ReadStructEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task<TField> ReadFieldBeginAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<TField>(cancellationToken);
+ }
+
+ var field = new TField
+ {
+ Type = (TType) await ReadByteAsync(cancellationToken)
+ };
+
+ if (field.Type != TType.Stop)
+ {
+ field.ID = await ReadI16Async(cancellationToken);
+ }
+
+ return field;
+ }
+
+ public override async Task ReadFieldEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task<TMap> ReadMapBeginAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<TMap>(cancellationToken);
+ }
+
+ var map = new TMap
+ {
+ KeyType = (TType) await ReadByteAsync(cancellationToken),
+ ValueType = (TType) await ReadByteAsync(cancellationToken),
+ Count = await ReadI32Async(cancellationToken)
+ };
+
+ return map;
+ }
+
+ public override async Task ReadMapEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task<TList> ReadListBeginAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<TList>(cancellationToken);
+ }
+
+ var list = new TList
+ {
+ ElementType = (TType) await ReadByteAsync(cancellationToken),
+ Count = await ReadI32Async(cancellationToken)
+ };
+
+ return list;
+ }
+
+ public override async Task ReadListEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task<TSet> ReadSetBeginAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<TSet>(cancellationToken);
+ }
+
+ var set = new TSet
+ {
+ ElementType = (TType) await ReadByteAsync(cancellationToken),
+ Count = await ReadI32Async(cancellationToken)
+ };
+
+ return set;
+ }
+
+ public override async Task ReadSetEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task<bool> ReadBoolAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<bool>(cancellationToken);
+ }
+
+ return await ReadByteAsync(cancellationToken) == 1;
+ }
+
+ public override async Task<sbyte> ReadByteAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<sbyte>(cancellationToken);
+ }
+
+ var bin = new byte[1];
+ await Trans.ReadAllAsync(bin, 0, 1, cancellationToken); //TODO: why readall ?
+ return (sbyte) bin[0];
+ }
+
+ public override async Task<short> ReadI16Async(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<short>(cancellationToken);
+ }
+
+ var i16In = new byte[2];
+ await Trans.ReadAllAsync(i16In, 0, 2, cancellationToken);
+ var result = (short) (((i16In[0] & 0xff) << 8) | i16In[1] & 0xff);
+ return result;
+ }
+
+ public override async Task<int> ReadI32Async(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<int>(cancellationToken);
+ }
+
+ var i32In = new byte[4];
+ await Trans.ReadAllAsync(i32In, 0, 4, cancellationToken);
+
+ var result =
+ ((i32In[0] & 0xff) << 24) |
+ ((i32In[1] & 0xff) << 16) |
+ ((i32In[2] & 0xff) << 8) |
+ i32In[3] & 0xff;
+
+ return result;
+ }
+
+#pragma warning disable 675
+
+ protected internal long CreateReadI64(byte[] buf)
+ {
+ var result =
+ ((long) (buf[0] & 0xff) << 56) |
+ ((long) (buf[1] & 0xff) << 48) |
+ ((long) (buf[2] & 0xff) << 40) |
+ ((long) (buf[3] & 0xff) << 32) |
+ ((long) (buf[4] & 0xff) << 24) |
+ ((long) (buf[5] & 0xff) << 16) |
+ ((long) (buf[6] & 0xff) << 8) |
+ buf[7] & 0xff;
+
+ return result;
+ }
+
+#pragma warning restore 675
+
+ public override async Task<long> ReadI64Async(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<long>(cancellationToken);
+ }
+
+ var i64In = new byte[8];
+ await Trans.ReadAllAsync(i64In, 0, 8, cancellationToken);
+ return CreateReadI64(i64In);
+ }
+
+ public override async Task<double> ReadDoubleAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<double>(cancellationToken);
+ }
+
+ var d = await ReadI64Async(cancellationToken);
+ return BitConverter.Int64BitsToDouble(d);
+ }
+
+ public override async Task<byte[]> ReadBinaryAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<byte[]>(cancellationToken);
+ }
+
+ var size = await ReadI32Async(cancellationToken);
+ var buf = new byte[size];
+ await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
+ return buf;
+ }
+
+ private async Task<string> ReadStringBodyAsync(int size, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled<string>(cancellationToken);
+ }
+
+ var buf = new byte[size];
+ await Trans.ReadAllAsync(buf, 0, size, cancellationToken);
+ return Encoding.UTF8.GetString(buf, 0, buf.Length);
+ }
+
+ public class Factory : TProtocolFactory
+ {
+ protected bool StrictRead;
+ protected bool StrictWrite;
+
+ public Factory()
+ : this(false, true)
+ {
+ }
+
+ public Factory(bool strictRead, bool strictWrite)
+ {
+ StrictRead = strictRead;
+ StrictWrite = strictWrite;
+ }
+
+ public override TProtocol GetProtocol(TTransport trans)
+ {
+ return new TBinaryProtocol(trans, StrictRead, StrictWrite);
+ }
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
new file mode 100644
index 0000000..e6c5dbd
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
@@ -0,0 +1,922 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol.Entities;
+using Thrift.Transport;
+
+namespace Thrift.Protocol
+{
+ //TODO: implementation of TProtocol
+
+ // ReSharper disable once InconsistentNaming
+ public class TCompactProtocol : TProtocol
+ {
+ private const byte ProtocolId = 0x82;
+ private const byte Version = 1;
+ private const byte VersionMask = 0x1f; // 0001 1111
+ private const byte TypeMask = 0xE0; // 1110 0000
+ private const byte TypeBits = 0x07; // 0000 0111
+ private const int TypeShiftAmount = 5;
+ private static readonly TStruct AnonymousStruct = new TStruct(string.Empty);
+ private static readonly TField Tstop = new TField(string.Empty, TType.Stop, 0);
+
+ // ReSharper disable once InconsistentNaming
+ private static readonly byte[] TTypeToCompactType = new byte[16];
+
+ /// <summary>
+ /// Used to keep track of the last field for the current and previous structs, so we can do the delta stuff.
+ /// </summary>
+ private readonly Stack<short> _lastField = new Stack<short>(15);
+
+ /// <summary>
+ /// If we encounter a boolean field begin, save the TField here so it can have the value incorporated.
+ /// </summary>
+ private TField? _booleanField;
+
+ /// <summary>
+ /// If we Read a field header, and it's a boolean field, save the boolean value here so that ReadBool can use it.
+ /// </summary>
+ private bool? _boolValue;
+
+ private short _lastFieldId;
+
+ public TCompactProtocol(TTransport trans)
+ : base(trans)
+ {
+ TTypeToCompactType[(int) TType.Stop] = Types.Stop;
+ TTypeToCompactType[(int) TType.Bool] = Types.BooleanTrue;
+ TTypeToCompactType[(int) TType.Byte] = Types.Byte;
+ TTypeToCompactType[(int) TType.I16] = Types.I16;
+ TTypeToCompactType[(int) TType.I32] = Types.I32;
+ TTypeToCompactType[(int) TType.I64] = Types.I64;
+ TTypeToCompactType[(int) TType.Double] = Types.Double;
+ TTypeToCompactType[(int) TType.String] = Types.Binary;
+ TTypeToCompactType[(int) TType.List] = Types.List;
+ TTypeToCompactType[(int) TType.Set] = Types.Set;
+ TTypeToCompactType[(int) TType.Map] = Types.Map;
+ TTypeToCompactType[(int) TType.Struct] = Types.Struct;
+ }
+
+ public void Reset()
+ {
+ _lastField.Clear();
+ _lastFieldId = 0;
+ }
+
+ public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await Trans.WriteAsync(new[] {ProtocolId}, cancellationToken);
+ await
+ Trans.WriteAsync(
+ new[] {(byte) ((Version & VersionMask) | (((uint) message.Type << TypeShiftAmount) & TypeMask))},
+ cancellationToken);
+
+ var bufferTuple = CreateWriteVarInt32((uint) message.SeqID);
+ await Trans.WriteAsync(bufferTuple.Item1, 0, bufferTuple.Item2, cancellationToken);
+
+ await WriteStringAsync(message.Name, cancellationToken);
+ }
+
+ public override async Task WriteMessageEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ /// <summary>
+ /// Write a struct begin. This doesn't actually put anything on the wire. We
+ /// use it as an opportunity to put special placeholder markers on the field
+ /// stack so we can get the field id deltas correct.
+ /// </summary>
+ public override async Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+
+ _lastField.Push(_lastFieldId);
+ _lastFieldId = 0;
+ }
+
+ public override async Task WriteStructEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+
+ _lastFieldId = _lastField.Pop();
+ }
+
+ private async Task WriteFieldBeginInternalAsync(TField field, byte typeOverride,
+ CancellationToken cancellationToken)
+ {
+ // if there's a exType override, use that.
+ var typeToWrite = typeOverride == 0xFF ? GetCompactType(field.Type) : typeOverride;
+
+ // check if we can use delta encoding for the field id
+ if ((field.ID > _lastFieldId) && (field.ID - _lastFieldId <= 15))
+ {
+ var b = (byte) (((field.ID - _lastFieldId) << 4) | typeToWrite);
+ // Write them together
+ await Trans.WriteAsync(new[] {b}, cancellationToken);
+ }
+ else
+ {
+ // Write them separate
+ await Trans.WriteAsync(new[] {typeToWrite}, cancellationToken);
+ await WriteI16Async(field.ID, cancellationToken);
+ }
+
+ _lastFieldId = field.ID;
+ }
+
+ public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken)
+ {
+ if (field.Type == TType.Bool)
+ {
+ _booleanField = field;
+ }
+ else
+ {
+ await WriteFieldBeginInternalAsync(field, 0xFF, cancellationToken);
+ }
+ }
+
+ public override async Task WriteFieldEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task WriteFieldStopAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await Trans.WriteAsync(new[] {Types.Stop}, cancellationToken);
+ }
+
+ protected async Task WriteCollectionBeginAsync(TType elemType, int size, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ /*
+ Abstract method for writing the start of lists and sets. List and sets on
+ the wire differ only by the exType indicator.
+ */
+
+ if (size <= 14)
+ {
+ await Trans.WriteAsync(new[] {(byte) ((size << 4) | GetCompactType(elemType))}, cancellationToken);
+ }
+ else
+ {
+ await Trans.WriteAsync(new[] {(byte) (0xf0 | GetCompactType(elemType))}, cancellationToken);
+
+ var bufferTuple = CreateWriteVarInt32((uint) size);
+ await Trans.WriteAsync(bufferTuple.Item1, 0, bufferTuple.Item2, cancellationToken);
+ }
+ }
+
+ public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken)
+ {
+ await WriteCollectionBeginAsync(list.ElementType, list.Count, cancellationToken);
+ }
+
+ public override async Task WriteListEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await WriteCollectionBeginAsync(set.ElementType, set.Count, cancellationToken);
+ }
+
+ public override async Task WriteSetEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ /*
+ Write a boolean value. Potentially, this could be a boolean field, in
+ which case the field header info isn't written yet. If so, decide what the
+ right exType header is for the value and then Write the field header.
+ Otherwise, Write a single byte.
+ */
+
+ if (_booleanField != null)
+ {
+ // we haven't written the field header yet
+ await
+ WriteFieldBeginInternalAsync(_booleanField.Value, b ? Types.BooleanTrue : Types.BooleanFalse,
+ cancellationToken);
+ _booleanField = null;
+ }
+ else
+ {
+ // we're not part of a field, so just Write the value.
+ await Trans.WriteAsync(new[] {b ? Types.BooleanTrue : Types.BooleanFalse}, cancellationToken);
+ }
+ }
+
+ public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ await Trans.WriteAsync(new[] {(byte) b}, cancellationToken);
+ }
+
+ public override async Task WriteI16Async(short i16, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ var bufferTuple = CreateWriteVarInt32(IntToZigzag(i16));
+ await Trans.WriteAsync(bufferTuple.Item1, 0, bufferTuple.Item2, cancellationToken);
+ }
+
+ protected internal Tuple<byte[], int> CreateWriteVarInt32(uint n)
+ {
+ // Write an i32 as a varint.Results in 1 - 5 bytes on the wire.
+ var i32Buf = new byte[5];
+ var idx = 0;
+
+ while (true)
+ {
+ if ((n & ~0x7F) == 0)
+ {
+ i32Buf[idx++] = (byte) n;
+ break;
+ }
+
+ i32Buf[idx++] = (byte) ((n & 0x7F) | 0x80);
+ n >>= 7;
+ }
+
+ return new Tuple<byte[], int>(i32Buf, idx);
+ }
+
+ public override async Task WriteI32Async(int i32, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ var bufferTuple = CreateWriteVarInt32(IntToZigzag(i32));
+ await Trans.WriteAsync(bufferTuple.Item1, 0, bufferTuple.Item2, cancellationToken);
+ }
+
+ protected internal Tuple<byte[], int> CreateWriteVarInt64(ulong n)
+ {
+ // Write an i64 as a varint. Results in 1-10 bytes on the wire.
+ var buf = new byte[10];
+ var idx = 0;
+
+ while (true)
+ {
+ if ((n & ~(ulong) 0x7FL) == 0)
+ {
+ buf[idx++] = (byte) n;
+ break;
+ }
+ buf[idx++] = (byte) ((n & 0x7F) | 0x80);
+ n >>= 7;
+ }
+
+ return new Tuple<byte[], int>(buf, idx);
+ }
+
+ public override async Task WriteI64Async(long i64, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ var bufferTuple = CreateWriteVarInt64(LongToZigzag(i64));
+ await Trans.WriteAsync(bufferTuple.Item1, 0, bufferTuple.Item2, cancellationToken);
+ }
+
+ public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ var data = new byte[8];
+ FixedLongToBytes(BitConverter.DoubleToInt64Bits(d), data, 0);
+ await Trans.WriteAsync(data, cancellationToken);
+ }
+
+ public override async Task WriteStringAsync(string str, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ var bytes = Encoding.UTF8.GetBytes(str);
+
+ var bufferTuple = CreateWriteVarInt32((uint) bytes.Length);
+ await Trans.WriteAsync(bufferTuple.Item1, 0, bufferTuple.Item2, cancellationToken);
+ await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
+ }
+
+ public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ var bufferTuple = CreateWriteVarInt32((uint) bytes.Length);
+ await Trans.WriteAsync(bufferTuple.Item1, 0, bufferTuple.Item2, cancellationToken);
+ await Trans.WriteAsync(bytes, 0, bytes.Length, cancellationToken);
+ }
+
+ public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return;
+ }
+
+ if (map.Count == 0)
+ {
+ await Trans.WriteAsync(new[] {(byte) 0}, cancellationToken);
+ }
+ else
+ {
+ var bufferTuple = CreateWriteVarInt32((uint) map.Count);
+ await Trans.WriteAsync(bufferTuple.Item1, 0, bufferTuple.Item2, cancellationToken);
+ await
+ Trans.WriteAsync(
+ new[] {(byte) ((GetCompactType(map.KeyType) << 4) | GetCompactType(map.ValueType))},
+ cancellationToken);
+ }
+ }
+
+ public override async Task WriteMapEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<TMessage>(cancellationToken);
+ }
+
+ var protocolId = (byte) await ReadByteAsync(cancellationToken);
+ if (protocolId != ProtocolId)
+ {
+ throw new TProtocolException($"Expected protocol id {ProtocolId:X} but got {protocolId:X}");
+ }
+
+ var versionAndType = (byte) await ReadByteAsync(cancellationToken);
+ var version = (byte) (versionAndType & VersionMask);
+
+ if (version != Version)
+ {
+ throw new TProtocolException($"Expected version {Version} but got {version}");
+ }
+
+ var type = (byte) ((versionAndType >> TypeShiftAmount) & TypeBits);
+ var seqid = (int) await ReadVarInt32Async(cancellationToken);
+ var messageName = await ReadStringAsync(cancellationToken);
+
+ return new TMessage(messageName, (TMessageType) type, seqid);
+ }
+
+ public override async Task ReadMessageEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task<TStruct> ReadStructBeginAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<TStruct>(cancellationToken);
+ }
+
+ // some magic is here )
+
+ _lastField.Push(_lastFieldId);
+ _lastFieldId = 0;
+
+ return AnonymousStruct;
+ }
+
+ public override async Task ReadStructEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+
+ /*
+ Doesn't actually consume any wire data, just removes the last field for
+ this struct from the field stack.
+ */
+
+ // consume the last field we Read off the wire.
+ _lastFieldId = _lastField.Pop();
+ }
+
+ public override async Task<TField> ReadFieldBeginAsync(CancellationToken cancellationToken)
+ {
+ // Read a field header off the wire.
+ var type = (byte) await ReadByteAsync(cancellationToken);
+ // if it's a stop, then we can return immediately, as the struct is over.
+ if (type == Types.Stop)
+ {
+ return Tstop;
+ }
+
+ short fieldId;
+ // mask off the 4 MSB of the exType header. it could contain a field id delta.
+ var modifier = (short) ((type & 0xf0) >> 4);
+ if (modifier == 0)
+ {
+ fieldId = await ReadI16Async(cancellationToken);
+ }
+ else
+ {
+ fieldId = (short) (_lastFieldId + modifier);
+ }
+
+ var field = new TField(string.Empty, GetTType((byte) (type & 0x0f)), fieldId);
+ // if this happens to be a boolean field, the value is encoded in the exType
+ if (IsBoolType(type))
+ {
+ _boolValue = (byte) (type & 0x0f) == Types.BooleanTrue;
+ }
+
+ // push the new field onto the field stack so we can keep the deltas going.
+ _lastFieldId = field.ID;
+ return field;
+ }
+
+ public override async Task ReadFieldEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task<TMap> ReadMapBeginAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled<TMap>(cancellationToken);
+ }
+
+ /*
+ Read a map header off the wire. If the size is zero, skip Reading the key
+ and value exType. This means that 0-length maps will yield TMaps without the
+ "correct" types.
+ */
+
+ var size = (int) await ReadVarInt32Async(cancellationToken);
+ var keyAndValueType = size == 0 ? (byte) 0 : (byte) await ReadByteAsync(cancellationToken);
+ return new TMap(GetTType((byte) (keyAndValueType >> 4)), GetTType((byte) (keyAndValueType & 0xf)), size);
+ }
+
+ public override async Task ReadMapEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task<TSet> ReadSetBeginAsync(CancellationToken cancellationToken)
+ {
+ /*
+ Read a set header off the wire. If the set size is 0-14, the size will
+ be packed into the element exType header. If it's a longer set, the 4 MSB
+ of the element exType header will be 0xF, and a varint will follow with the
+ true size.
+ */
+
+ return new TSet(await ReadListBeginAsync(cancellationToken));
+ }
+
+ public override async Task<bool> ReadBoolAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<bool>(cancellationToken);
+ }
+
+ /*
+ Read a boolean off the wire. If this is a boolean field, the value should
+ already have been Read during ReadFieldBegin, so we'll just consume the
+ pre-stored value. Otherwise, Read a byte.
+ */
+
+ if (_boolValue != null)
+ {
+ var result = _boolValue.Value;
+ _boolValue = null;
+ return result;
+ }
+
+ return await ReadByteAsync(cancellationToken) == Types.BooleanTrue;
+ }
+
+ public override async Task<sbyte> ReadByteAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<sbyte>(cancellationToken);
+ }
+
+ // Read a single byte off the wire. Nothing interesting here.
+ var buf = new byte[1];
+ await Trans.ReadAllAsync(buf, 0, 1, cancellationToken);
+ return (sbyte) buf[0];
+ }
+
+ public override async Task<short> ReadI16Async(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<short>(cancellationToken);
+ }
+
+ return (short) ZigzagToInt(await ReadVarInt32Async(cancellationToken));
+ }
+
+ public override async Task<int> ReadI32Async(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<int>(cancellationToken);
+ }
+
+ return ZigzagToInt(await ReadVarInt32Async(cancellationToken));
+ }
+
+ public override async Task<long> ReadI64Async(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<long>(cancellationToken);
+ }
+
+ return ZigzagToLong(await ReadVarInt64Async(cancellationToken));
+ }
+
+ public override async Task<double> ReadDoubleAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<double>(cancellationToken);
+ }
+
+ var longBits = new byte[8];
+ await Trans.ReadAllAsync(longBits, 0, 8, cancellationToken);
+
+ return BitConverter.Int64BitsToDouble(BytesToLong(longBits));
+ }
+
+ public override async Task<string> ReadStringAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled<string>(cancellationToken);
+ }
+
+ // Reads a byte[] (via ReadBinary), and then UTF-8 decodes it.
+ var length = (int) await ReadVarInt32Async(cancellationToken);
+
+ if (length == 0)
+ {
+ return string.Empty;
+ }
+
+ var buf = new byte[length];
+ await Trans.ReadAllAsync(buf, 0, length, cancellationToken);
+
+ return Encoding.UTF8.GetString(buf);
+ }
+
+ public override async Task<byte[]> ReadBinaryAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<byte[]>(cancellationToken);
+ }
+
+ // Read a byte[] from the wire.
+ var length = (int) await ReadVarInt32Async(cancellationToken);
+ if (length == 0)
+ {
+ return new byte[0];
+ }
+
+ var buf = new byte[length];
+ await Trans.ReadAllAsync(buf, 0, length, cancellationToken);
+ return buf;
+ }
+
+ public override async Task<TList> ReadListBeginAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled<TList>(cancellationToken);
+ }
+
+ /*
+ Read a list header off the wire. If the list size is 0-14, the size will
+ be packed into the element exType header. If it's a longer list, the 4 MSB
+ of the element exType header will be 0xF, and a varint will follow with the
+ true size.
+ */
+
+ var sizeAndType = (byte) await ReadByteAsync(cancellationToken);
+ var size = (sizeAndType >> 4) & 0x0f;
+ if (size == 15)
+ {
+ size = (int) await ReadVarInt32Async(cancellationToken);
+ }
+
+ var type = GetTType(sizeAndType);
+ return new TList(type, size);
+ }
+
+ public override async Task ReadListEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task ReadSetEndAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ private static byte GetCompactType(TType ttype)
+ {
+ // Given a TType value, find the appropriate TCompactProtocol.Types constant.
+ return TTypeToCompactType[(int) ttype];
+ }
+
+
+ private async Task<uint> ReadVarInt32Async(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<uint>(cancellationToken);
+ }
+
+ /*
+ Read an i32 from the wire as a varint. The MSB of each byte is set
+ if there is another byte to follow. This can Read up to 5 bytes.
+ */
+
+ uint result = 0;
+ var shift = 0;
+
+ while (true)
+ {
+ var b = (byte) await ReadByteAsync(cancellationToken);
+ result |= (uint) (b & 0x7f) << shift;
+ if ((b & 0x80) != 0x80)
+ {
+ break;
+ }
+ shift += 7;
+ }
+
+ return result;
+ }
+
+ private async Task<ulong> ReadVarInt64Async(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<uint>(cancellationToken);
+ }
+
+ /*
+ Read an i64 from the wire as a proper varint. The MSB of each byte is set
+ if there is another byte to follow. This can Read up to 10 bytes.
+ */
+
+ var shift = 0;
+ ulong result = 0;
+ while (true)
+ {
+ var b = (byte) await ReadByteAsync(cancellationToken);
+ result |= (ulong) (b & 0x7f) << shift;
+ if ((b & 0x80) != 0x80)
+ {
+ break;
+ }
+ shift += 7;
+ }
+
+ return result;
+ }
+
+ private static int ZigzagToInt(uint n)
+ {
+ return (int) (n >> 1) ^ -(int) (n & 1);
+ }
+
+ private static long ZigzagToLong(ulong n)
+ {
+ return (long) (n >> 1) ^ -(long) (n & 1);
+ }
+
+ private static long BytesToLong(byte[] bytes)
+ {
+ /*
+ Note that it's important that the mask bytes are long literals,
+ otherwise they'll default to ints, and when you shift an int left 56 bits,
+ you just get a messed up int.
+ */
+
+ return
+ ((bytes[7] & 0xffL) << 56) |
+ ((bytes[6] & 0xffL) << 48) |
+ ((bytes[5] & 0xffL) << 40) |
+ ((bytes[4] & 0xffL) << 32) |
+ ((bytes[3] & 0xffL) << 24) |
+ ((bytes[2] & 0xffL) << 16) |
+ ((bytes[1] & 0xffL) << 8) |
+ (bytes[0] & 0xffL);
+ }
+
+ private static bool IsBoolType(byte b)
+ {
+ var lowerNibble = b & 0x0f;
+ return (lowerNibble == Types.BooleanTrue) || (lowerNibble == Types.BooleanFalse);
+ }
+
+ private static TType GetTType(byte type)
+ {
+ // Given a TCompactProtocol.Types constant, convert it to its corresponding TType value.
+ switch ((byte) (type & 0x0f))
+ {
+ case Types.Stop:
+ return TType.Stop;
+ case Types.BooleanFalse:
+ case Types.BooleanTrue:
+ return TType.Bool;
+ case Types.Byte:
+ return TType.Byte;
+ case Types.I16:
+ return TType.I16;
+ case Types.I32:
+ return TType.I32;
+ case Types.I64:
+ return TType.I64;
+ case Types.Double:
+ return TType.Double;
+ case Types.Binary:
+ return TType.String;
+ case Types.List:
+ return TType.List;
+ case Types.Set:
+ return TType.Set;
+ case Types.Map:
+ return TType.Map;
+ case Types.Struct:
+ return TType.Struct;
+ default:
+ throw new TProtocolException($"Don't know what exType: {(byte) (type & 0x0f)}");
+ }
+ }
+
+ private static ulong LongToZigzag(long n)
+ {
+ // Convert l into a zigzag long. This allows negative numbers to be represented compactly as a varint
+ return (ulong) (n << 1) ^ (ulong) (n >> 63);
+ }
+
+ private static uint IntToZigzag(int n)
+ {
+ // Convert n into a zigzag int. This allows negative numbers to be represented compactly as a varint
+ return (uint) (n << 1) ^ (uint) (n >> 31);
+ }
+
+ private static void FixedLongToBytes(long n, byte[] buf, int off)
+ {
+ // Convert a long into little-endian bytes in buf starting at off and going until off+7.
+ buf[off + 0] = (byte) (n & 0xff);
+ buf[off + 1] = (byte) ((n >> 8) & 0xff);
+ buf[off + 2] = (byte) ((n >> 16) & 0xff);
+ buf[off + 3] = (byte) ((n >> 24) & 0xff);
+ buf[off + 4] = (byte) ((n >> 32) & 0xff);
+ buf[off + 5] = (byte) ((n >> 40) & 0xff);
+ buf[off + 6] = (byte) ((n >> 48) & 0xff);
+ buf[off + 7] = (byte) ((n >> 56) & 0xff);
+ }
+
+ public class Factory : TProtocolFactory
+ {
+ public override TProtocol GetProtocol(TTransport trans)
+ {
+ return new TCompactProtocol(trans);
+ }
+ }
+
+ /// <summary>
+ /// All of the on-wire exType codes.
+ /// </summary>
+ private static class Types
+ {
+ public const byte Stop = 0x00;
+ public const byte BooleanTrue = 0x01;
+ public const byte BooleanFalse = 0x02;
+ public const byte Byte = 0x03;
+ public const byte I16 = 0x04;
+ public const byte I32 = 0x05;
+ public const byte I64 = 0x06;
+ public const byte Double = 0x07;
+ public const byte Binary = 0x08;
+ public const byte List = 0x09;
+ public const byte Set = 0x0A;
+ public const byte Map = 0x0B;
+ public const byte Struct = 0x0C;
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
new file mode 100644
index 0000000..1298052
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
@@ -0,0 +1,981 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol.Entities;
+using Thrift.Protocol.Utilities;
+using Thrift.Transport;
+
+namespace Thrift.Protocol
+{
+ /// <summary>
+ /// JSON protocol implementation for thrift.
+ /// This is a full-featured protocol supporting Write and Read.
+ /// Please see the C++ class header for a detailed description of the
+ /// protocol's wire format.
+ /// Adapted from the Java version.
+ /// </summary>
+ // ReSharper disable once InconsistentNaming
+ public class TJsonProtocol : TProtocol
+ {
+ private const long Version = 1;
+
+ // Temporary buffer used by several methods
+ private readonly byte[] _tempBuffer = new byte[4];
+
+ // Current context that we are in
+ protected JSONBaseContext Context;
+
+ // Stack of nested contexts that we may be in
+ protected Stack<JSONBaseContext> ContextStack = new Stack<JSONBaseContext>();
+
+ // Reader that manages a 1-byte buffer
+ protected LookaheadReader Reader;
+
+ // Default encoding
+ protected Encoding Utf8Encoding = Encoding.UTF8;
+
+ /// <summary>
+ /// TJsonProtocol Constructor
+ /// </summary>
+ public TJsonProtocol(TTransport trans)
+ : base(trans)
+ {
+ Context = new JSONBaseContext(this);
+ Reader = new LookaheadReader(this);
+ }
+
+ /// <summary>
+ /// Push a new JSON context onto the stack.
+ /// </summary>
+ protected void PushContext(JSONBaseContext c)
+ {
+ ContextStack.Push(Context);
+ Context = c;
+ }
+
+ /// <summary>
+ /// Pop the last JSON context off the stack
+ /// </summary>
+ protected void PopContext()
+ {
+ Context = ContextStack.Pop();
+ }
+
+ /// <summary>
+ /// Read a byte that must match b[0]; otherwise an exception is thrown.
+ /// Marked protected to avoid synthetic accessor in JSONListContext.Read
+ /// and JSONPairContext.Read
+ /// </summary>
+ protected async Task ReadJsonSyntaxCharAsync(byte[] bytes, CancellationToken cancellationToken)
+ {
+ var ch = await Reader.ReadAsync(cancellationToken);
+ if (ch != bytes[0])
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA, $"Unexpected character: {(char) ch}");
+ }
+ }
+
+ /// <summary>
+ /// Write the bytes in array buf as a JSON characters, escaping as needed
+ /// </summary>
+ private async Task WriteJsonStringAsync(byte[] bytes, CancellationToken cancellationToken)
+ {
+ await Context.WriteConditionalDelimiterAsync(cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
+
+ var len = bytes.Length;
+ for (var i = 0; i < len; i++)
+ {
+ if ((bytes[i] & 0x00FF) >= 0x30)
+ {
+ if (bytes[i] == TJSONProtocolConstants.Backslash[0])
+ {
+ await Trans.WriteAsync(TJSONProtocolConstants.Backslash, cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Backslash, cancellationToken);
+ }
+ else
+ {
+ await Trans.WriteAsync(bytes.ToArray(), i, 1, cancellationToken);
+ }
+ }
+ else
+ {
+ _tempBuffer[0] = TJSONProtocolConstants.JsonCharTable[bytes[i]];
+ if (_tempBuffer[0] == 1)
+ {
+ await Trans.WriteAsync(bytes, i, 1, cancellationToken);
+ }
+ else if (_tempBuffer[0] > 1)
+ {
+ await Trans.WriteAsync(TJSONProtocolConstants.Backslash, cancellationToken);
+ await Trans.WriteAsync(_tempBuffer, 0, 1, cancellationToken);
+ }
+ else
+ {
+ await Trans.WriteAsync(TJSONProtocolConstants.EscSequences, cancellationToken);
+ _tempBuffer[0] = TJSONProtocolHelper.ToHexChar((byte) (bytes[i] >> 4));
+ _tempBuffer[1] = TJSONProtocolHelper.ToHexChar(bytes[i]);
+ await Trans.WriteAsync(_tempBuffer, 0, 2, cancellationToken);
+ }
+ }
+ }
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
+ }
+
+ /// <summary>
+ /// Write out number as a JSON value. If the context dictates so, it will be
+ /// wrapped in quotes to output as a JSON string.
+ /// </summary>
+ private async Task WriteJsonIntegerAsync(long num, CancellationToken cancellationToken)
+ {
+ await Context.WriteConditionalDelimiterAsync(cancellationToken);
+ var str = num.ToString();
+
+ var escapeNum = Context.EscapeNumbers();
+ if (escapeNum)
+ {
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
+ }
+
+ var bytes = Utf8Encoding.GetBytes(str);
+ await Trans.WriteAsync(bytes, cancellationToken);
+
+ if (escapeNum)
+ {
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
+ }
+ }
+
+ /// <summary>
+ /// Write out a double as a JSON value. If it is NaN or infinity or if the
+ /// context dictates escaping, Write out as JSON string.
+ /// </summary>
+ private async Task WriteJsonDoubleAsync(double num, CancellationToken cancellationToken)
+ {
+ await Context.WriteConditionalDelimiterAsync(cancellationToken);
+ var str = num.ToString("G17", CultureInfo.InvariantCulture);
+ var special = false;
+
+ switch (str[0])
+ {
+ case 'N': // NaN
+ case 'I': // Infinity
+ special = true;
+ break;
+ case '-':
+ if (str[1] == 'I')
+ {
+ // -Infinity
+ special = true;
+ }
+ break;
+ }
+
+ var escapeNum = special || Context.EscapeNumbers();
+
+ if (escapeNum)
+ {
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
+ }
+
+ await Trans.WriteAsync(Utf8Encoding.GetBytes(str), cancellationToken);
+
+ if (escapeNum)
+ {
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
+ }
+ }
+
+ /// <summary>
+ /// Write out contents of byte array b as a JSON string with base-64 encoded
+ /// data
+ /// </summary>
+ private async Task WriteJsonBase64Async(byte[] bytes, CancellationToken cancellationToken)
+ {
+ await Context.WriteConditionalDelimiterAsync(cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
+
+ var len = bytes.Length;
+ var off = 0;
+
+ while (len >= 3)
+ {
+ // Encode 3 bytes at a time
+ TBase64Utils.Encode(bytes, off, 3, _tempBuffer, 0);
+ await Trans.WriteAsync(_tempBuffer, 0, 4, cancellationToken);
+ off += 3;
+ len -= 3;
+ }
+
+ if (len > 0)
+ {
+ // Encode remainder
+ TBase64Utils.Encode(bytes, off, len, _tempBuffer, 0);
+ await Trans.WriteAsync(_tempBuffer, 0, len + 1, cancellationToken);
+ }
+
+ await Trans.WriteAsync(TJSONProtocolConstants.Quote, cancellationToken);
+ }
+
+ private async Task WriteJsonObjectStartAsync(CancellationToken cancellationToken)
+ {
+ await Context.WriteConditionalDelimiterAsync(cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.LeftBrace, cancellationToken);
+ PushContext(new JSONPairContext(this));
+ }
+
+ private async Task WriteJsonObjectEndAsync(CancellationToken cancellationToken)
+ {
+ PopContext();
+ await Trans.WriteAsync(TJSONProtocolConstants.RightBrace, cancellationToken);
+ }
+
+ private async Task WriteJsonArrayStartAsync(CancellationToken cancellationToken)
+ {
+ await Context.WriteConditionalDelimiterAsync(cancellationToken);
+ await Trans.WriteAsync(TJSONProtocolConstants.LeftBracket, cancellationToken);
+ PushContext(new JSONListContext(this));
+ }
+
+ private async Task WriteJsonArrayEndAsync(CancellationToken cancellationToken)
+ {
+ PopContext();
+ await Trans.WriteAsync(TJSONProtocolConstants.RightBracket, cancellationToken);
+ }
+
+ public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
+ {
+ await WriteJsonArrayStartAsync(cancellationToken);
+ await WriteJsonIntegerAsync(Version, cancellationToken);
+
+ var b = Utf8Encoding.GetBytes(message.Name);
+ await WriteJsonStringAsync(b, cancellationToken);
+
+ await WriteJsonIntegerAsync((long) message.Type, cancellationToken);
+ await WriteJsonIntegerAsync(message.SeqID, cancellationToken);
+ }
+
+ public override async Task WriteMessageEndAsync(CancellationToken cancellationToken)
+ {
+ await WriteJsonArrayEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
+ {
+ await WriteJsonObjectStartAsync(cancellationToken);
+ }
+
+ public override async Task WriteStructEndAsync(CancellationToken cancellationToken)
+ {
+ await WriteJsonObjectEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken)
+ {
+ await WriteJsonIntegerAsync(field.ID, cancellationToken);
+ await WriteJsonObjectStartAsync(cancellationToken);
+ await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(field.Type), cancellationToken);
+ }
+
+ public override async Task WriteFieldEndAsync(CancellationToken cancellationToken)
+ {
+ await WriteJsonObjectEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteFieldStopAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
+ {
+ await WriteJsonArrayStartAsync(cancellationToken);
+ await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(map.KeyType), cancellationToken);
+ await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(map.ValueType), cancellationToken);
+ await WriteJsonIntegerAsync(map.Count, cancellationToken);
+ await WriteJsonObjectStartAsync(cancellationToken);
+ }
+
+ public override async Task WriteMapEndAsync(CancellationToken cancellationToken)
+ {
+ await WriteJsonObjectEndAsync(cancellationToken);
+ await WriteJsonArrayEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken)
+ {
+ await WriteJsonArrayStartAsync(cancellationToken);
+ await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(list.ElementType), cancellationToken);
+ await WriteJsonIntegerAsync(list.Count, cancellationToken);
+ }
+
+ public override async Task WriteListEndAsync(CancellationToken cancellationToken)
+ {
+ await WriteJsonArrayEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken)
+ {
+ await WriteJsonArrayStartAsync(cancellationToken);
+ await WriteJsonStringAsync(TJSONProtocolHelper.GetTypeNameForTypeId(set.ElementType), cancellationToken);
+ await WriteJsonIntegerAsync(set.Count, cancellationToken);
+ }
+
+ public override async Task WriteSetEndAsync(CancellationToken cancellationToken)
+ {
+ await WriteJsonArrayEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken)
+ {
+ await WriteJsonIntegerAsync(b ? 1 : 0, cancellationToken);
+ }
+
+ public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken)
+ {
+ await WriteJsonIntegerAsync(b, cancellationToken);
+ }
+
+ public override async Task WriteI16Async(short i16, CancellationToken cancellationToken)
+ {
+ await WriteJsonIntegerAsync(i16, cancellationToken);
+ }
+
+ public override async Task WriteI32Async(int i32, CancellationToken cancellationToken)
+ {
+ await WriteJsonIntegerAsync(i32, cancellationToken);
+ }
+
+ public override async Task WriteI64Async(long i64, CancellationToken cancellationToken)
+ {
+ await WriteJsonIntegerAsync(i64, cancellationToken);
+ }
+
+ public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken)
+ {
+ await WriteJsonDoubleAsync(d, cancellationToken);
+ }
+
+ public override async Task WriteStringAsync(string s, CancellationToken cancellationToken)
+ {
+ var b = Utf8Encoding.GetBytes(s);
+ await WriteJsonStringAsync(b, cancellationToken);
+ }
+
+ public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
+ {
+ await WriteJsonBase64Async(bytes, cancellationToken);
+ }
+
+ /// <summary>
+ /// Read in a JSON string, unescaping as appropriate.. Skip Reading from the
+ /// context if skipContext is true.
+ /// </summary>
+ private async Task<byte[]> ReadJsonStringAsync(bool skipContext, CancellationToken cancellationToken)
+ {
+ using (var buffer = new MemoryStream())
+ {
+ var codeunits = new List<char>();
+
+
+ if (!skipContext)
+ {
+ await Context.ReadConditionalDelimiterAsync(cancellationToken);
+ }
+
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken);
+
+ while (true)
+ {
+ var ch = await Reader.ReadAsync(cancellationToken);
+ if (ch == TJSONProtocolConstants.Quote[0])
+ {
+ break;
+ }
+
+ // escaped?
+ if (ch != TJSONProtocolConstants.EscSequences[0])
+ {
+ await buffer.WriteAsync(new[] {ch}, 0, 1, cancellationToken);
+ continue;
+ }
+
+ // distinguish between \uXXXX and \?
+ ch = await Reader.ReadAsync(cancellationToken);
+ if (ch != TJSONProtocolConstants.EscSequences[1]) // control chars like \n
+ {
+ var off = Array.IndexOf(TJSONProtocolConstants.EscapeChars, (char) ch);
+ if (off == -1)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected control char");
+ }
+ ch = TJSONProtocolConstants.EscapeCharValues[off];
+ await buffer.WriteAsync(new[] {ch}, 0, 1, cancellationToken);
+ continue;
+ }
+
+ // it's \uXXXX
+ await Trans.ReadAllAsync(_tempBuffer, 0, 4, cancellationToken);
+
+ var wch = (short) ((TJSONProtocolHelper.ToHexVal(_tempBuffer[0]) << 12) +
+ (TJSONProtocolHelper.ToHexVal(_tempBuffer[1]) << 8) +
+ (TJSONProtocolHelper.ToHexVal(_tempBuffer[2]) << 4) +
+ TJSONProtocolHelper.ToHexVal(_tempBuffer[3]));
+
+ if (char.IsHighSurrogate((char) wch))
+ {
+ if (codeunits.Count > 0)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected low surrogate char");
+ }
+ codeunits.Add((char) wch);
+ }
+ else if (char.IsLowSurrogate((char) wch))
+ {
+ if (codeunits.Count == 0)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected high surrogate char");
+ }
+
+ codeunits.Add((char) wch);
+ var tmp = Utf8Encoding.GetBytes(codeunits.ToArray());
+ await buffer.WriteAsync(tmp, 0, tmp.Length, cancellationToken);
+ codeunits.Clear();
+ }
+ else
+ {
+ var tmp = Utf8Encoding.GetBytes(new[] {(char) wch});
+ await buffer.WriteAsync(tmp, 0, tmp.Length, cancellationToken);
+ }
+ }
+
+ if (codeunits.Count > 0)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected low surrogate char");
+ }
+
+ return buffer.ToArray();
+ }
+ }
+
+ /// <summary>
+ /// Read in a sequence of characters that are all valid in JSON numbers. Does
+ /// not do a complete regex check to validate that this is actually a number.
+ /// </summary>
+ private async Task<string> ReadJsonNumericCharsAsync(CancellationToken cancellationToken)
+ {
+ var strbld = new StringBuilder();
+ while (true)
+ {
+ //TODO: workaround for primitive types with TJsonProtocol, think - how to rewrite into more easy form without exceptions
+ try
+ {
+ var ch = await Reader.PeekAsync(cancellationToken);
+ if (!TJSONProtocolHelper.IsJsonNumeric(ch))
+ {
+ break;
+ }
+ var c = (char)await Reader.ReadAsync(cancellationToken);
+ strbld.Append(c);
+ }
+ catch (TTransportException)
+ {
+ break;
+ }
+ }
+ return strbld.ToString();
+ }
+
+ /// <summary>
+ /// Read in a JSON number. If the context dictates, Read in enclosing quotes.
+ /// </summary>
+ private async Task<long> ReadJsonIntegerAsync(CancellationToken cancellationToken)
+ {
+ await Context.ReadConditionalDelimiterAsync(cancellationToken);
+ if (Context.EscapeNumbers())
+ {
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken);
+ }
+
+ var str = await ReadJsonNumericCharsAsync(cancellationToken);
+ if (Context.EscapeNumbers())
+ {
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken);
+ }
+
+ try
+ {
+ return long.Parse(str);
+ }
+ catch (FormatException)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA, "Bad data encounted in numeric data");
+ }
+ }
+
+ /// <summary>
+ /// Read in a JSON double value. Throw if the value is not wrapped in quotes
+ /// when expected or if wrapped in quotes when not expected.
+ /// </summary>
+ private async Task<double> ReadJsonDoubleAsync(CancellationToken cancellationToken)
+ {
+ await Context.ReadConditionalDelimiterAsync(cancellationToken);
+ if (await Reader.PeekAsync(cancellationToken) == TJSONProtocolConstants.Quote[0])
+ {
+ var arr = await ReadJsonStringAsync(true, cancellationToken);
+ var dub = double.Parse(Utf8Encoding.GetString(arr, 0, arr.Length), CultureInfo.InvariantCulture);
+
+ if (!Context.EscapeNumbers() && !double.IsNaN(dub) && !double.IsInfinity(dub))
+ {
+ // Throw exception -- we should not be in a string in this case
+ throw new TProtocolException(TProtocolException.INVALID_DATA, "Numeric data unexpectedly quoted");
+ }
+
+ return dub;
+ }
+
+ if (Context.EscapeNumbers())
+ {
+ // This will throw - we should have had a quote if escapeNum == true
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Quote, cancellationToken);
+ }
+
+ try
+ {
+ return double.Parse(await ReadJsonNumericCharsAsync(cancellationToken), CultureInfo.InvariantCulture);
+ }
+ catch (FormatException)
+ {
+ throw new TProtocolException(TProtocolException.INVALID_DATA, "Bad data encounted in numeric data");
+ }
+ }
+
+ /// <summary>
+ /// Read in a JSON string containing base-64 encoded data and decode it.
+ /// </summary>
+ private async Task<byte[]> ReadJsonBase64Async(CancellationToken cancellationToken)
+ {
+ var b = await ReadJsonStringAsync(false, cancellationToken);
+ var len = b.Length;
+ var off = 0;
+ var size = 0;
+
+ // reduce len to ignore fill bytes
+ while ((len > 0) && (b[len - 1] == '='))
+ {
+ --len;
+ }
+
+ // read & decode full byte triplets = 4 source bytes
+ while (len > 4)
+ {
+ // Decode 4 bytes at a time
+ TBase64Utils.Decode(b, off, 4, b, size); // NB: decoded in place
+ off += 4;
+ len -= 4;
+ size += 3;
+ }
+
+ // Don't decode if we hit the end or got a single leftover byte (invalid
+ // base64 but legal for skip of regular string exType)
+ if (len > 1)
+ {
+ // Decode remainder
+ TBase64Utils.Decode(b, off, len, b, size); // NB: decoded in place
+ size += len - 1;
+ }
+
+ // Sadly we must copy the byte[] (any way around this?)
+ var result = new byte[size];
+ Array.Copy(b, 0, result, 0, size);
+ return result;
+ }
+
+ private async Task ReadJsonObjectStartAsync(CancellationToken cancellationToken)
+ {
+ await Context.ReadConditionalDelimiterAsync(cancellationToken);
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.LeftBrace, cancellationToken);
+ PushContext(new JSONPairContext(this));
+ }
+
+ private async Task ReadJsonObjectEndAsync(CancellationToken cancellationToken)
+ {
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.RightBrace, cancellationToken);
+ PopContext();
+ }
+
+ private async Task ReadJsonArrayStartAsync(CancellationToken cancellationToken)
+ {
+ await Context.ReadConditionalDelimiterAsync(cancellationToken);
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.LeftBracket, cancellationToken);
+ PushContext(new JSONListContext(this));
+ }
+
+ private async Task ReadJsonArrayEndAsync(CancellationToken cancellationToken)
+ {
+ await ReadJsonSyntaxCharAsync(TJSONProtocolConstants.RightBracket, cancellationToken);
+ PopContext();
+ }
+
+ public override async Task<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
+ {
+ var message = new TMessage();
+ await ReadJsonArrayStartAsync(cancellationToken);
+ if (await ReadJsonIntegerAsync(cancellationToken) != Version)
+ {
+ throw new TProtocolException(TProtocolException.BAD_VERSION, "Message contained bad version.");
+ }
+
+ var buf = await ReadJsonStringAsync(false, cancellationToken);
+ message.Name = Utf8Encoding.GetString(buf, 0, buf.Length);
+ message.Type = (TMessageType) await ReadJsonIntegerAsync(cancellationToken);
+ message.SeqID = (int) await ReadJsonIntegerAsync(cancellationToken);
+ return message;
+ }
+
+ public override async Task ReadMessageEndAsync(CancellationToken cancellationToken)
+ {
+ await ReadJsonArrayEndAsync(cancellationToken);
+ }
+
+ public override async Task<TStruct> ReadStructBeginAsync(CancellationToken cancellationToken)
+ {
+ await ReadJsonObjectStartAsync(cancellationToken);
+ return new TStruct();
+ }
+
+ public override async Task ReadStructEndAsync(CancellationToken cancellationToken)
+ {
+ await ReadJsonObjectEndAsync(cancellationToken);
+ }
+
+ public override async Task<TField> ReadFieldBeginAsync(CancellationToken cancellationToken)
+ {
+ var field = new TField();
+ var ch = await Reader.PeekAsync(cancellationToken);
+ if (ch == TJSONProtocolConstants.RightBrace[0])
+ {
+ field.Type = TType.Stop;
+ }
+ else
+ {
+ field.ID = (short) await ReadJsonIntegerAsync(cancellationToken);
+ await ReadJsonObjectStartAsync(cancellationToken);
+ field.Type = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
+ }
+ return field;
+ }
+
+ public override async Task ReadFieldEndAsync(CancellationToken cancellationToken)
+ {
+ await ReadJsonObjectEndAsync(cancellationToken);
+ }
+
+ public override async Task<TMap> ReadMapBeginAsync(CancellationToken cancellationToken)
+ {
+ var map = new TMap();
+ await ReadJsonArrayStartAsync(cancellationToken);
+ map.KeyType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
+ map.ValueType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
+ map.Count = (int) await ReadJsonIntegerAsync(cancellationToken);
+ await ReadJsonObjectStartAsync(cancellationToken);
+ return map;
+ }
+
+ public override async Task ReadMapEndAsync(CancellationToken cancellationToken)
+ {
+ await ReadJsonObjectEndAsync(cancellationToken);
+ await ReadJsonArrayEndAsync(cancellationToken);
+ }
+
+ public override async Task<TList> ReadListBeginAsync(CancellationToken cancellationToken)
+ {
+ var list = new TList();
+ await ReadJsonArrayStartAsync(cancellationToken);
+ list.ElementType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
+ list.Count = (int) await ReadJsonIntegerAsync(cancellationToken);
+ return list;
+ }
+
+ public override async Task ReadListEndAsync(CancellationToken cancellationToken)
+ {
+ await ReadJsonArrayEndAsync(cancellationToken);
+ }
+
+ public override async Task<TSet> ReadSetBeginAsync(CancellationToken cancellationToken)
+ {
+ var set = new TSet();
+ await ReadJsonArrayStartAsync(cancellationToken);
+ set.ElementType = TJSONProtocolHelper.GetTypeIdForTypeName(await ReadJsonStringAsync(false, cancellationToken));
+ set.Count = (int) await ReadJsonIntegerAsync(cancellationToken);
+ return set;
+ }
+
+ public override async Task ReadSetEndAsync(CancellationToken cancellationToken)
+ {
+ await ReadJsonArrayEndAsync(cancellationToken);
+ }
+
+ public override async Task<bool> ReadBoolAsync(CancellationToken cancellationToken)
+ {
+ return await ReadJsonIntegerAsync(cancellationToken) != 0;
+ }
+
+ public override async Task<sbyte> ReadByteAsync(CancellationToken cancellationToken)
+ {
+ return (sbyte) await ReadJsonIntegerAsync(cancellationToken);
+ }
+
+ public override async Task<short> ReadI16Async(CancellationToken cancellationToken)
+ {
+ return (short) await ReadJsonIntegerAsync(cancellationToken);
+ }
+
+ public override async Task<int> ReadI32Async(CancellationToken cancellationToken)
+ {
+ return (int) await ReadJsonIntegerAsync(cancellationToken);
+ }
+
+ public override async Task<long> ReadI64Async(CancellationToken cancellationToken)
+ {
+ return await ReadJsonIntegerAsync(cancellationToken);
+ }
+
+ public override async Task<double> ReadDoubleAsync(CancellationToken cancellationToken)
+ {
+ return await ReadJsonDoubleAsync(cancellationToken);
+ }
+
+ public override async Task<string> ReadStringAsync(CancellationToken cancellationToken)
+ {
+ var buf = await ReadJsonStringAsync(false, cancellationToken);
+ return Utf8Encoding.GetString(buf, 0, buf.Length);
+ }
+
+ public override async Task<byte[]> ReadBinaryAsync(CancellationToken cancellationToken)
+ {
+ return await ReadJsonBase64Async(cancellationToken);
+ }
+
+ /// <summary>
+ /// Factory for JSON protocol objects
+ /// </summary>
+ public class Factory : TProtocolFactory
+ {
+ public override TProtocol GetProtocol(TTransport trans)
+ {
+ return new TJsonProtocol(trans);
+ }
+ }
+
+ /// <summary>
+ /// Base class for tracking JSON contexts that may require
+ /// inserting/Reading additional JSON syntax characters
+ /// This base context does nothing.
+ /// </summary>
+ protected class JSONBaseContext
+ {
+ protected TJsonProtocol Proto;
+
+ public JSONBaseContext(TJsonProtocol proto)
+ {
+ Proto = proto;
+ }
+
+ public virtual async Task WriteConditionalDelimiterAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public virtual async Task ReadConditionalDelimiterAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public virtual bool EscapeNumbers()
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Context for JSON lists. Will insert/Read commas before each item except
+ /// for the first one
+ /// </summary>
+ protected class JSONListContext : JSONBaseContext
+ {
+ private bool _first = true;
+
+ public JSONListContext(TJsonProtocol protocol)
+ : base(protocol)
+ {
+ }
+
+ public override async Task WriteConditionalDelimiterAsync(CancellationToken cancellationToken)
+ {
+ if (_first)
+ {
+ _first = false;
+ }
+ else
+ {
+ await Proto.Trans.WriteAsync(TJSONProtocolConstants.Comma, cancellationToken);
+ }
+ }
+
+ public override async Task ReadConditionalDelimiterAsync(CancellationToken cancellationToken)
+ {
+ if (_first)
+ {
+ _first = false;
+ }
+ else
+ {
+ await Proto.ReadJsonSyntaxCharAsync(TJSONProtocolConstants.Comma, cancellationToken);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Context for JSON records. Will insert/Read colons before the value portion
+ /// of each record pair, and commas before each key except the first. In
+ /// addition, will indicate that numbers in the key position need to be
+ /// escaped in quotes (since JSON keys must be strings).
+ /// </summary>
+ // ReSharper disable once InconsistentNaming
+ protected class JSONPairContext : JSONBaseContext
+ {
+ private bool _colon = true;
+
+ private bool _first = true;
+
+ public JSONPairContext(TJsonProtocol proto)
+ : base(proto)
+ {
+ }
+
+ public override async Task WriteConditionalDelimiterAsync(CancellationToken cancellationToken)
+ {
+ if (_first)
+ {
+ _first = false;
+ _colon = true;
+ }
+ else
+ {
+ await Proto.Trans.WriteAsync(_colon ? TJSONProtocolConstants.Colon : TJSONProtocolConstants.Comma, cancellationToken);
+ _colon = !_colon;
+ }
+ }
+
+ public override async Task ReadConditionalDelimiterAsync(CancellationToken cancellationToken)
+ {
+ if (_first)
+ {
+ _first = false;
+ _colon = true;
+ }
+ else
+ {
+ await Proto.ReadJsonSyntaxCharAsync(_colon ? TJSONProtocolConstants.Colon : TJSONProtocolConstants.Comma, cancellationToken);
+ _colon = !_colon;
+ }
+ }
+
+ public override bool EscapeNumbers()
+ {
+ return _colon;
+ }
+ }
+
+ /// <summary>
+ /// Holds up to one byte from the transport
+ /// </summary>
+ protected class LookaheadReader
+ {
+ private readonly byte[] _data = new byte[1];
+
+ private bool _hasData;
+ protected TJsonProtocol Proto;
+
+ public LookaheadReader(TJsonProtocol proto)
+ {
+ Proto = proto;
+ }
+
+ /// <summary>
+ /// Return and consume the next byte to be Read, either taking it from the
+ /// data buffer if present or getting it from the transport otherwise.
+ /// </summary>
+ public async Task<byte> ReadAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<byte>(cancellationToken);
+ }
+
+ if (_hasData)
+ {
+ _hasData = false;
+ }
+ else
+ {
+ // find more easy way to avoid exception on reading primitive types
+ await Proto.Trans.ReadAllAsync(_data, 0, 1, cancellationToken);
+ }
+ return _data[0];
+ }
+
+ /// <summary>
+ /// Return the next byte to be Read without consuming, filling the data
+ /// buffer if it has not been filled alReady.
+ /// </summary>
+ public async Task<byte> PeekAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<byte>(cancellationToken);
+ }
+
+ if (!_hasData)
+ {
+ // find more easy way to avoid exception on reading primitive types
+ await Proto.Trans.ReadAllAsync(_data, 0, 1, cancellationToken);
+ }
+ _hasData = true;
+ return _data[0];
+ }
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Protocol/TMultiplexedProtocol.cs b/lib/netstd/Thrift/Protocol/TMultiplexedProtocol.cs
new file mode 100644
index 0000000..fbc8c05
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/TMultiplexedProtocol.cs
@@ -0,0 +1,91 @@
+// 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.
+
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol.Entities;
+
+namespace Thrift.Protocol
+{
+ /**
+ * TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift
+ * client to communicate with a multiplexing Thrift server, by prepending the service name
+ * to the function name during function calls.
+ *
+ * NOTE: THIS IS NOT TO BE USED BY SERVERS.
+ * On the server, use TMultiplexedProcessor to handle requests from a multiplexing client.
+ *
+ * This example uses a single socket transport to invoke two services:
+ *
+ * TSocketTransport transport = new TSocketTransport("localhost", 9090);
+ * transport.open();
+ *
+ * TBinaryProtocol protocol = new TBinaryProtocol(transport);
+ *
+ * TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
+ * Calculator.Client service = new Calculator.Client(mp);
+ *
+ * TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
+ * WeatherReport.Client service2 = new WeatherReport.Client(mp2);
+ *
+ * System.out.println(service.add(2,2));
+ * System.out.println(service2.getTemperature());
+ *
+ */
+
+ //TODO: implementation of TProtocol
+
+ // ReSharper disable once InconsistentNaming
+ public class TMultiplexedProtocol : TProtocolDecorator
+ {
+ /** Used to delimit the service name from the function name */
+ public const string Separator = ":";
+
+ private readonly string _serviceName;
+
+ /**
+ * Wrap the specified protocol, allowing it to be used to communicate with a
+ * multiplexing server. The <code>serviceName</code> is required as it is
+ * prepended to the message header so that the multiplexing server can broker
+ * the function call to the proper service.
+ *
+ * Args:
+ * protocol Your communication protocol of choice, e.g. TBinaryProtocol
+ * serviceName The service name of the service communicating via this protocol.
+ */
+
+ public TMultiplexedProtocol(TProtocol protocol, string serviceName)
+ : base(protocol)
+ {
+ _serviceName = serviceName;
+ }
+
+ public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
+ {
+ switch (message.Type)
+ {
+ case TMessageType.Call:
+ case TMessageType.Oneway:
+ await base.WriteMessageBeginAsync(new TMessage($"{_serviceName}{Separator}{message.Name}", message.Type, message.SeqID), cancellationToken);
+ break;
+ default:
+ await base.WriteMessageBeginAsync(message, cancellationToken);
+ break;
+ }
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Protocol/TProtocol.cs b/lib/netstd/Thrift/Protocol/TProtocol.cs
new file mode 100644
index 0000000..1bc91eb
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/TProtocol.cs
@@ -0,0 +1,376 @@
+// 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.
+
+using System;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol.Entities;
+using Thrift.Transport;
+
+namespace Thrift.Protocol
+{
+ // ReSharper disable once InconsistentNaming
+ public abstract class TProtocol : IDisposable
+ {
+ public const int DefaultRecursionDepth = 64;
+ private bool _isDisposed;
+ protected int RecursionDepth;
+
+ protected TTransport Trans;
+
+ protected TProtocol(TTransport trans)
+ {
+ Trans = trans;
+ RecursionLimit = DefaultRecursionDepth;
+ RecursionDepth = 0;
+ }
+
+ public TTransport Transport => Trans;
+
+ protected int RecursionLimit { get; set; }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ public void IncrementRecursionDepth()
+ {
+ if (RecursionDepth < RecursionLimit)
+ {
+ ++RecursionDepth;
+ }
+ else
+ {
+ throw new TProtocolException(TProtocolException.DEPTH_LIMIT, "Depth limit exceeded");
+ }
+ }
+
+ public void DecrementRecursionDepth()
+ {
+ --RecursionDepth;
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_isDisposed)
+ {
+ if (disposing)
+ {
+ (Trans as IDisposable)?.Dispose();
+ }
+ }
+ _isDisposed = true;
+ }
+
+ public virtual async Task WriteMessageBeginAsync(TMessage message)
+ {
+ await WriteMessageBeginAsync(message, CancellationToken.None);
+ }
+
+ public abstract Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken);
+
+ public virtual async Task WriteMessageEndAsync()
+ {
+ await WriteMessageEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task WriteMessageEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task WriteStructBeginAsync(TStruct @struct)
+ {
+ await WriteStructBeginAsync(@struct, CancellationToken.None);
+ }
+
+ public abstract Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken);
+
+ public virtual async Task WriteStructEndAsync()
+ {
+ await WriteStructEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task WriteStructEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task WriteFieldBeginAsync(TField field)
+ {
+ await WriteFieldBeginAsync(field, CancellationToken.None);
+ }
+
+ public abstract Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken);
+
+ public virtual async Task WriteFieldEndAsync()
+ {
+ await WriteFieldEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task WriteFieldEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task WriteFieldStopAsync()
+ {
+ await WriteFieldStopAsync(CancellationToken.None);
+ }
+
+ public abstract Task WriteFieldStopAsync(CancellationToken cancellationToken);
+
+ public virtual async Task WriteMapBeginAsync(TMap map)
+ {
+ await WriteMapBeginAsync(map, CancellationToken.None);
+ }
+
+ public abstract Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken);
+
+ public virtual async Task WriteMapEndAsync()
+ {
+ await WriteMapEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task WriteMapEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task WriteListBeginAsync(TList list)
+ {
+ await WriteListBeginAsync(list, CancellationToken.None);
+ }
+
+ public abstract Task WriteListBeginAsync(TList list, CancellationToken cancellationToken);
+
+ public virtual async Task WriteListEndAsync()
+ {
+ await WriteListEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task WriteListEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task WriteSetBeginAsync(TSet set)
+ {
+ await WriteSetBeginAsync(set, CancellationToken.None);
+ }
+
+ public abstract Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken);
+
+ public virtual async Task WriteSetEndAsync()
+ {
+ await WriteSetEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task WriteSetEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task WriteBoolAsync(bool b)
+ {
+ await WriteBoolAsync(b, CancellationToken.None);
+ }
+
+ public abstract Task WriteBoolAsync(bool b, CancellationToken cancellationToken);
+
+ public virtual async Task WriteByteAsync(sbyte b)
+ {
+ await WriteByteAsync(b, CancellationToken.None);
+ }
+
+ public abstract Task WriteByteAsync(sbyte b, CancellationToken cancellationToken);
+
+ public virtual async Task WriteI16Async(short i16)
+ {
+ await WriteI16Async(i16, CancellationToken.None);
+ }
+
+ public abstract Task WriteI16Async(short i16, CancellationToken cancellationToken);
+
+ public virtual async Task WriteI32Async(int i32)
+ {
+ await WriteI32Async(i32, CancellationToken.None);
+ }
+
+ public abstract Task WriteI32Async(int i32, CancellationToken cancellationToken);
+
+ public virtual async Task WriteI64Async(long i64)
+ {
+ await WriteI64Async(i64, CancellationToken.None);
+ }
+
+ public abstract Task WriteI64Async(long i64, CancellationToken cancellationToken);
+
+ public virtual async Task WriteDoubleAsync(double d)
+ {
+ await WriteDoubleAsync(d, CancellationToken.None);
+ }
+
+ public abstract Task WriteDoubleAsync(double d, CancellationToken cancellationToken);
+
+ public virtual async Task WriteStringAsync(string s)
+ {
+ await WriteStringAsync(s, CancellationToken.None);
+ }
+
+ public virtual async Task WriteStringAsync(string s, CancellationToken cancellationToken)
+ {
+ var bytes = Encoding.UTF8.GetBytes(s);
+ await WriteBinaryAsync(bytes, cancellationToken);
+ }
+
+ public virtual async Task WriteBinaryAsync(byte[] bytes)
+ {
+ await WriteBinaryAsync(bytes, CancellationToken.None);
+ }
+
+ public abstract Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken);
+
+ public virtual async Task<TMessage> ReadMessageBeginAsync()
+ {
+ return await ReadMessageBeginAsync(CancellationToken.None);
+ }
+
+ public abstract Task<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken);
+
+ public virtual async Task ReadMessageEndAsync()
+ {
+ await ReadMessageEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task ReadMessageEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task<TStruct> ReadStructBeginAsync()
+ {
+ return await ReadStructBeginAsync(CancellationToken.None);
+ }
+
+ public abstract Task<TStruct> ReadStructBeginAsync(CancellationToken cancellationToken);
+
+ public virtual async Task ReadStructEndAsync()
+ {
+ await ReadStructEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task ReadStructEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task<TField> ReadFieldBeginAsync()
+ {
+ return await ReadFieldBeginAsync(CancellationToken.None);
+ }
+
+ public abstract Task<TField> ReadFieldBeginAsync(CancellationToken cancellationToken);
+
+ public virtual async Task ReadFieldEndAsync()
+ {
+ await ReadFieldEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task ReadFieldEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task<TMap> ReadMapBeginAsync()
+ {
+ return await ReadMapBeginAsync(CancellationToken.None);
+ }
+
+ public abstract Task<TMap> ReadMapBeginAsync(CancellationToken cancellationToken);
+
+ public virtual async Task ReadMapEndAsync()
+ {
+ await ReadMapEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task ReadMapEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task<TList> ReadListBeginAsync()
+ {
+ return await ReadListBeginAsync(CancellationToken.None);
+ }
+
+ public abstract Task<TList> ReadListBeginAsync(CancellationToken cancellationToken);
+
+ public virtual async Task ReadListEndAsync()
+ {
+ await ReadListEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task ReadListEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task<TSet> ReadSetBeginAsync()
+ {
+ return await ReadSetBeginAsync(CancellationToken.None);
+ }
+
+ public abstract Task<TSet> ReadSetBeginAsync(CancellationToken cancellationToken);
+
+ public virtual async Task ReadSetEndAsync()
+ {
+ await ReadSetEndAsync(CancellationToken.None);
+ }
+
+ public abstract Task ReadSetEndAsync(CancellationToken cancellationToken);
+
+ public virtual async Task<bool> ReadBoolAsync()
+ {
+ return await ReadBoolAsync(CancellationToken.None);
+ }
+
+ public abstract Task<bool> ReadBoolAsync(CancellationToken cancellationToken);
+
+ public virtual async Task<sbyte> ReadByteAsync()
+ {
+ return await ReadByteAsync(CancellationToken.None);
+ }
+
+ public abstract Task<sbyte> ReadByteAsync(CancellationToken cancellationToken);
+
+ public virtual async Task<short> ReadI16Async()
+ {
+ return await ReadI16Async(CancellationToken.None);
+ }
+
+ public abstract Task<short> ReadI16Async(CancellationToken cancellationToken);
+
+ public virtual async Task<int> ReadI32Async()
+ {
+ return await ReadI32Async(CancellationToken.None);
+ }
+
+ public abstract Task<int> ReadI32Async(CancellationToken cancellationToken);
+
+ public virtual async Task<long> ReadI64Async()
+ {
+ return await ReadI64Async(CancellationToken.None);
+ }
+
+ public abstract Task<long> ReadI64Async(CancellationToken cancellationToken);
+
+ public virtual async Task<double> ReadDoubleAsync()
+ {
+ return await ReadDoubleAsync(CancellationToken.None);
+ }
+
+ public abstract Task<double> ReadDoubleAsync(CancellationToken cancellationToken);
+
+ public virtual async Task<string> ReadStringAsync()
+ {
+ return await ReadStringAsync(CancellationToken.None);
+ }
+
+ public virtual async Task<string> ReadStringAsync(CancellationToken cancellationToken)
+ {
+ var buf = await ReadBinaryAsync(cancellationToken);
+ return Encoding.UTF8.GetString(buf, 0, buf.Length);
+ }
+
+ public virtual async Task<byte[]> ReadBinaryAsync()
+ {
+ return await ReadBinaryAsync(CancellationToken.None);
+ }
+
+ public abstract Task<byte[]> ReadBinaryAsync(CancellationToken cancellationToken);
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs b/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs
new file mode 100644
index 0000000..c8a433d
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/TProtocolDecorator.cs
@@ -0,0 +1,247 @@
+// 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.
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol.Entities;
+
+namespace Thrift.Protocol
+{
+ // ReSharper disable once InconsistentNaming
+ /// <summary>
+ /// TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
+ /// providing a way to author concise concrete decorator subclasses.While it has
+ /// no abstract methods, it is marked abstract as a reminder that by itself,
+ /// it does not modify the behaviour of the enclosed TProtocol.
+ /// </summary>
+ public abstract class TProtocolDecorator : TProtocol
+ {
+ private readonly TProtocol _wrappedProtocol;
+
+ protected TProtocolDecorator(TProtocol protocol)
+ : base(protocol.Transport)
+ {
+ _wrappedProtocol = protocol ?? throw new ArgumentNullException(nameof(protocol));
+ }
+
+ public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteMessageBeginAsync(message, cancellationToken);
+ }
+
+ public override async Task WriteMessageEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteMessageEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteStructBeginAsync(TStruct @struct, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteStructBeginAsync(@struct, cancellationToken);
+ }
+
+ public override async Task WriteStructEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteStructEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteFieldBeginAsync(TField field, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteFieldBeginAsync(field, cancellationToken);
+ }
+
+ public override async Task WriteFieldEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteFieldEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteFieldStopAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteFieldStopAsync(cancellationToken);
+ }
+
+ public override async Task WriteMapBeginAsync(TMap map, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteMapBeginAsync(map, cancellationToken);
+ }
+
+ public override async Task WriteMapEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteMapEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteListBeginAsync(TList list, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteListBeginAsync(list, cancellationToken);
+ }
+
+ public override async Task WriteListEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteListEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteSetBeginAsync(TSet set, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteSetBeginAsync(set, cancellationToken);
+ }
+
+ public override async Task WriteSetEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteSetEndAsync(cancellationToken);
+ }
+
+ public override async Task WriteBoolAsync(bool b, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteBoolAsync(b, cancellationToken);
+ }
+
+ public override async Task WriteByteAsync(sbyte b, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteByteAsync(b, cancellationToken);
+ }
+
+ public override async Task WriteI16Async(short i16, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteI16Async(i16, cancellationToken);
+ }
+
+ public override async Task WriteI32Async(int i32, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteI32Async(i32, cancellationToken);
+ }
+
+ public override async Task WriteI64Async(long i64, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteI64Async(i64, cancellationToken);
+ }
+
+ public override async Task WriteDoubleAsync(double d, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteDoubleAsync(d, cancellationToken);
+ }
+
+ public override async Task WriteStringAsync(string s, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteStringAsync(s, cancellationToken);
+ }
+
+ public override async Task WriteBinaryAsync(byte[] bytes, CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.WriteBinaryAsync(bytes, cancellationToken);
+ }
+
+ public override async Task<TMessage> ReadMessageBeginAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadMessageBeginAsync(cancellationToken);
+ }
+
+ public override async Task ReadMessageEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.ReadMessageEndAsync(cancellationToken);
+ }
+
+ public override async Task<TStruct> ReadStructBeginAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadStructBeginAsync(cancellationToken);
+ }
+
+ public override async Task ReadStructEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.ReadStructEndAsync(cancellationToken);
+ }
+
+ public override async Task<TField> ReadFieldBeginAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadFieldBeginAsync(cancellationToken);
+ }
+
+ public override async Task ReadFieldEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.ReadFieldEndAsync(cancellationToken);
+ }
+
+ public override async Task<TMap> ReadMapBeginAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadMapBeginAsync(cancellationToken);
+ }
+
+ public override async Task ReadMapEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.ReadMapEndAsync(cancellationToken);
+ }
+
+ public override async Task<TList> ReadListBeginAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadListBeginAsync(cancellationToken);
+ }
+
+ public override async Task ReadListEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.ReadListEndAsync(cancellationToken);
+ }
+
+ public override async Task<TSet> ReadSetBeginAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadSetBeginAsync(cancellationToken);
+ }
+
+ public override async Task ReadSetEndAsync(CancellationToken cancellationToken)
+ {
+ await _wrappedProtocol.ReadSetEndAsync(cancellationToken);
+ }
+
+ public override async Task<bool> ReadBoolAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadBoolAsync(cancellationToken);
+ }
+
+ public override async Task<sbyte> ReadByteAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadByteAsync(cancellationToken);
+ }
+
+ public override async Task<short> ReadI16Async(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadI16Async(cancellationToken);
+ }
+
+ public override async Task<int> ReadI32Async(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadI32Async(cancellationToken);
+ }
+
+ public override async Task<long> ReadI64Async(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadI64Async(cancellationToken);
+ }
+
+ public override async Task<double> ReadDoubleAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadDoubleAsync(cancellationToken);
+ }
+
+ public override async Task<string> ReadStringAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadStringAsync(cancellationToken);
+ }
+
+ public override async Task<byte[]> ReadBinaryAsync(CancellationToken cancellationToken)
+ {
+ return await _wrappedProtocol.ReadBinaryAsync(cancellationToken);
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/TProtocolException.cs b/lib/netstd/Thrift/Protocol/TProtocolException.cs
new file mode 100644
index 0000000..328babd
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/TProtocolException.cs
@@ -0,0 +1,62 @@
+// 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.
+
+// ReSharper disable InconsistentNaming
+using System;
+
+namespace Thrift.Protocol
+{
+ public class TProtocolException : TException
+ {
+ // do not rename public constants - they used in generated files
+ public const int UNKNOWN = 0;
+ public const int INVALID_DATA = 1;
+ public const int NEGATIVE_SIZE = 2;
+ public const int SIZE_LIMIT = 3;
+ public const int BAD_VERSION = 4;
+ public const int NOT_IMPLEMENTED = 5;
+ public const int DEPTH_LIMIT = 6;
+
+ protected int Type = UNKNOWN;
+
+ public TProtocolException()
+ {
+ }
+
+ public TProtocolException(int type, Exception inner = null)
+ : base(string.Empty, inner)
+ {
+ Type = type;
+ }
+
+ public TProtocolException(int type, string message, Exception inner = null)
+ : base(message, inner)
+ {
+ Type = type;
+ }
+
+ public TProtocolException(string message, Exception inner = null)
+ : base(message, inner)
+ {
+ }
+
+ public int GetExceptionType()
+ {
+ return Type;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/TProtocolFactory.cs b/lib/netstd/Thrift/Protocol/TProtocolFactory.cs
new file mode 100644
index 0000000..31b0514
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/TProtocolFactory.cs
@@ -0,0 +1,27 @@
+// 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.
+
+using Thrift.Transport;
+
+namespace Thrift.Protocol
+{
+ // ReSharper disable once InconsistentNaming
+ public abstract class TProtocolFactory
+ {
+ public abstract TProtocol GetProtocol(TTransport trans);
+ }
+}
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TBase64Utils.cs b/lib/netstd/Thrift/Protocol/Utilities/TBase64Utils.cs
new file mode 100644
index 0000000..90b8f88
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Utilities/TBase64Utils.cs
@@ -0,0 +1,101 @@
+// 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.
+
+using System;
+
+namespace Thrift.Protocol.Utilities
+{
+ // ReSharper disable once InconsistentNaming
+ internal static class TBase64Utils
+ {
+ //TODO: Constants
+ //TODO: Check for args
+ //TODO: Unitests
+
+ internal const string EncodeTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ private static readonly int[] DecodeTable =
+ {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+ };
+
+ internal static void Encode(byte[] src, int srcOff, int len, byte[] dst, int dstOff)
+ {
+ if (src == null)
+ {
+ throw new ArgumentNullException(nameof(src));
+ }
+
+ dst[dstOff] = (byte) EncodeTable[(src[srcOff] >> 2) & 0x3F];
+
+ if (len == 3)
+ {
+ dst[dstOff + 1] = (byte) EncodeTable[((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F)];
+ dst[dstOff + 2] = (byte) EncodeTable[((src[srcOff + 1] << 2) & 0x3C) | ((src[srcOff + 2] >> 6) & 0x03)];
+ dst[dstOff + 3] = (byte) EncodeTable[src[srcOff + 2] & 0x3F];
+ }
+ else if (len == 2)
+ {
+ dst[dstOff + 1] = (byte) EncodeTable[((src[srcOff] << 4) & 0x30) | ((src[srcOff + 1] >> 4) & 0x0F)];
+ dst[dstOff + 2] = (byte) EncodeTable[(src[srcOff + 1] << 2) & 0x3C];
+ }
+ else
+ {
+ // len == 1
+ dst[dstOff + 1] = (byte) EncodeTable[(src[srcOff] << 4) & 0x30];
+ }
+ }
+
+ internal static void Decode(byte[] src, int srcOff, int len, byte[] dst, int dstOff)
+ {
+ if (src == null)
+ {
+ throw new ArgumentNullException(nameof(src));
+ }
+
+ dst[dstOff] = (byte) ((DecodeTable[src[srcOff] & 0x0FF] << 2) | (DecodeTable[src[srcOff + 1] & 0x0FF] >> 4));
+
+ if (len > 2)
+ {
+ dst[dstOff + 1] =
+ (byte)
+ (((DecodeTable[src[srcOff + 1] & 0x0FF] << 4) & 0xF0) | (DecodeTable[src[srcOff + 2] & 0x0FF] >> 2));
+ if (len > 3)
+ {
+ dst[dstOff + 2] =
+ (byte)
+ (((DecodeTable[src[srcOff + 2] & 0x0FF] << 6) & 0xC0) | DecodeTable[src[srcOff + 3] & 0x0FF]);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs
new file mode 100644
index 0000000..6cc1302
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs
@@ -0,0 +1,61 @@
+// 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.
+
+namespace Thrift.Protocol.Utilities
+{
+ // ReSharper disable once InconsistentNaming
+ public static class TJSONProtocolConstants
+ {
+ //TODO Check for performance for reusing ImmutableArray from System.Collections.Immutable (https://blogs.msdn.microsoft.com/dotnet/2013/06/24/please-welcome-immutablearrayt/)
+ // can be possible to get better performance and also better GC
+
+ public static readonly byte[] Comma = {(byte) ','};
+ public static readonly byte[] Colon = {(byte) ':'};
+ public static readonly byte[] LeftBrace = {(byte) '{'};
+ public static readonly byte[] RightBrace = {(byte) '}'};
+ public static readonly byte[] LeftBracket = {(byte) '['};
+ public static readonly byte[] RightBracket = {(byte) ']'};
+ public static readonly byte[] Quote = {(byte) '"'};
+ public static readonly byte[] Backslash = {(byte) '\\'};
+
+ public static readonly byte[] JsonCharTable =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, (byte) 'b', (byte) 't', (byte) 'n', 0, (byte) 'f', (byte) 'r', 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, (byte) '"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+ };
+
+ public static readonly char[] EscapeChars = "\"\\/bfnrt".ToCharArray();
+ public static readonly byte[] EscapeCharValues = {(byte) '"', (byte) '\\', (byte) '/', (byte) '\b', (byte) '\f', (byte) '\n', (byte) '\r', (byte) '\t'};
+ public static readonly byte[] EscSequences = {(byte) '\\', (byte) 'u', (byte) '0', (byte) '0'};
+
+ public static class TypeNames
+ {
+ public static readonly byte[] NameBool = { (byte)'t', (byte)'f' };
+ public static readonly byte[] NameByte = { (byte)'i', (byte)'8' };
+ public static readonly byte[] NameI16 = { (byte)'i', (byte)'1', (byte)'6' };
+ public static readonly byte[] NameI32 = { (byte)'i', (byte)'3', (byte)'2' };
+ public static readonly byte[] NameI64 = { (byte)'i', (byte)'6', (byte)'4' };
+ public static readonly byte[] NameDouble = { (byte)'d', (byte)'b', (byte)'l' };
+ public static readonly byte[] NameStruct = { (byte)'r', (byte)'e', (byte)'c' };
+ public static readonly byte[] NameString = { (byte)'s', (byte)'t', (byte)'r' };
+ public static readonly byte[] NameMap = { (byte)'m', (byte)'a', (byte)'p' };
+ public static readonly byte[] NameList = { (byte)'l', (byte)'s', (byte)'t' };
+ public static readonly byte[] NameSet = { (byte)'s', (byte)'e', (byte)'t' };
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs
new file mode 100644
index 0000000..ff49ebe
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolHelper.cs
@@ -0,0 +1,176 @@
+// 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.
+
+using Thrift.Protocol.Entities;
+
+namespace Thrift.Protocol.Utilities
+{
+ // ReSharper disable once InconsistentNaming
+ public static class TJSONProtocolHelper
+ {
+ public static byte[] GetTypeNameForTypeId(TType typeId)
+ {
+ switch (typeId)
+ {
+ case TType.Bool:
+ return TJSONProtocolConstants.TypeNames.NameBool;
+ case TType.Byte:
+ return TJSONProtocolConstants.TypeNames.NameByte;
+ case TType.I16:
+ return TJSONProtocolConstants.TypeNames.NameI16;
+ case TType.I32:
+ return TJSONProtocolConstants.TypeNames.NameI32;
+ case TType.I64:
+ return TJSONProtocolConstants.TypeNames.NameI64;
+ case TType.Double:
+ return TJSONProtocolConstants.TypeNames.NameDouble;
+ case TType.String:
+ return TJSONProtocolConstants.TypeNames.NameString;
+ case TType.Struct:
+ return TJSONProtocolConstants.TypeNames.NameStruct;
+ case TType.Map:
+ return TJSONProtocolConstants.TypeNames.NameMap;
+ case TType.Set:
+ return TJSONProtocolConstants.TypeNames.NameSet;
+ case TType.List:
+ return TJSONProtocolConstants.TypeNames.NameList;
+ default:
+ throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized exType");
+ }
+ }
+
+ public static TType GetTypeIdForTypeName(byte[] name)
+ {
+ var result = TType.Stop;
+ if (name.Length > 1)
+ {
+ switch (name[0])
+ {
+ case (byte) 'd':
+ result = TType.Double;
+ break;
+ case (byte) 'i':
+ switch (name[1])
+ {
+ case (byte) '8':
+ result = TType.Byte;
+ break;
+ case (byte) '1':
+ result = TType.I16;
+ break;
+ case (byte) '3':
+ result = TType.I32;
+ break;
+ case (byte) '6':
+ result = TType.I64;
+ break;
+ }
+ break;
+ case (byte) 'l':
+ result = TType.List;
+ break;
+ case (byte) 'm':
+ result = TType.Map;
+ break;
+ case (byte) 'r':
+ result = TType.Struct;
+ break;
+ case (byte) 's':
+ if (name[1] == (byte) 't')
+ {
+ result = TType.String;
+ }
+ else if (name[1] == (byte) 'e')
+ {
+ result = TType.Set;
+ }
+ break;
+ case (byte) 't':
+ result = TType.Bool;
+ break;
+ }
+ }
+ if (result == TType.Stop)
+ {
+ throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized exType");
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Return true if the given byte could be a valid part of a JSON number.
+ /// </summary>
+ public static bool IsJsonNumeric(byte b)
+ {
+ switch (b)
+ {
+ case (byte)'+':
+ case (byte)'-':
+ case (byte)'.':
+ case (byte)'0':
+ case (byte)'1':
+ case (byte)'2':
+ case (byte)'3':
+ case (byte)'4':
+ case (byte)'5':
+ case (byte)'6':
+ case (byte)'7':
+ case (byte)'8':
+ case (byte)'9':
+ case (byte)'E':
+ case (byte)'e':
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its
+ /// corresponding hex value
+ /// </summary>
+ public static byte ToHexVal(byte ch)
+ {
+ if (ch >= '0' && ch <= '9')
+ {
+ return (byte)((char)ch - '0');
+ }
+
+ if (ch >= 'a' && ch <= 'f')
+ {
+ ch += 10;
+ return (byte)((char)ch - 'a');
+ }
+
+ throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected hex character");
+ }
+
+ /// <summary>
+ /// Convert a byte containing a hex value to its corresponding hex character
+ /// </summary>
+ public static byte ToHexChar(byte val)
+ {
+ val &= 0x0F;
+ if (val < 10)
+ {
+ return (byte)((char)val + '0');
+ }
+ val -= 10;
+ return (byte)((char)val + 'a');
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs b/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs
new file mode 100644
index 0000000..18f92d8
--- /dev/null
+++ b/lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs
@@ -0,0 +1,110 @@
+// 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.
+
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol.Entities;
+
+namespace Thrift.Protocol.Utilities
+{
+ // ReSharper disable once InconsistentNaming
+ public static class TProtocolUtil
+ {
+ public static async Task SkipAsync(TProtocol protocol, TType type, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+
+ protocol.IncrementRecursionDepth();
+ try
+ {
+ switch (type)
+ {
+ case TType.Bool:
+ await protocol.ReadBoolAsync(cancellationToken);
+ break;
+ case TType.Byte:
+ await protocol.ReadByteAsync(cancellationToken);
+ break;
+ case TType.I16:
+ await protocol.ReadI16Async(cancellationToken);
+ break;
+ case TType.I32:
+ await protocol.ReadI32Async(cancellationToken);
+ break;
+ case TType.I64:
+ await protocol.ReadI64Async(cancellationToken);
+ break;
+ case TType.Double:
+ await protocol.ReadDoubleAsync(cancellationToken);
+ break;
+ case TType.String:
+ // Don't try to decode the string, just skip it.
+ await protocol.ReadBinaryAsync(cancellationToken);
+ break;
+ case TType.Struct:
+ await protocol.ReadStructBeginAsync(cancellationToken);
+ while (true)
+ {
+ var field = await protocol.ReadFieldBeginAsync(cancellationToken);
+ if (field.Type == TType.Stop)
+ {
+ break;
+ }
+ await SkipAsync(protocol, field.Type, cancellationToken);
+ await protocol.ReadFieldEndAsync(cancellationToken);
+ }
+ await protocol.ReadStructEndAsync(cancellationToken);
+ break;
+ case TType.Map:
+ var map = await protocol.ReadMapBeginAsync(cancellationToken);
+ for (var i = 0; i < map.Count; i++)
+ {
+ await SkipAsync(protocol, map.KeyType, cancellationToken);
+ await SkipAsync(protocol, map.ValueType, cancellationToken);
+ }
+ await protocol.ReadMapEndAsync(cancellationToken);
+ break;
+ case TType.Set:
+ var set = await protocol.ReadSetBeginAsync(cancellationToken);
+ for (var i = 0; i < set.Count; i++)
+ {
+ await SkipAsync(protocol, set.ElementType, cancellationToken);
+ }
+ await protocol.ReadSetEndAsync(cancellationToken);
+ break;
+ case TType.List:
+ var list = await protocol.ReadListBeginAsync(cancellationToken);
+ for (var i = 0; i < list.Count; i++)
+ {
+ await SkipAsync(protocol, list.ElementType, cancellationToken);
+ }
+ await protocol.ReadListEndAsync(cancellationToken);
+ break;
+ default:
+ throw new TProtocolException(TProtocolException.INVALID_DATA, "Unknown data type " + type.ToString("d"));
+ }
+ }
+ finally
+ {
+ protocol.DecrementRecursionDepth();
+ }
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Server/TServer.cs b/lib/netstd/Thrift/Server/TServer.cs
new file mode 100644
index 0000000..f40f2b7
--- /dev/null
+++ b/lib/netstd/Thrift/Server/TServer.cs
@@ -0,0 +1,87 @@
+// 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.
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Processor;
+
+namespace Thrift.Server
+{
+ // ReSharper disable once InconsistentNaming
+ public abstract class TServer
+ {
+ protected readonly ILogger Logger;
+ protected TProtocolFactory InputProtocolFactory;
+ protected TTransportFactory InputTransportFactory;
+ protected ITProcessorFactory ProcessorFactory;
+ protected TProtocolFactory OutputProtocolFactory;
+ protected TTransportFactory OutputTransportFactory;
+
+ protected TServerEventHandler ServerEventHandler;
+ protected TServerTransport ServerTransport;
+
+ protected TServer(ITProcessorFactory processorFactory, TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory, TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory,
+ ILogger logger = null)
+ {
+ ProcessorFactory = processorFactory ?? throw new ArgumentNullException(nameof(processorFactory));
+ ServerTransport = serverTransport;
+ InputTransportFactory = inputTransportFactory ?? new TTransportFactory();
+ OutputTransportFactory = outputTransportFactory ?? new TTransportFactory();
+ InputProtocolFactory = inputProtocolFactory ?? throw new ArgumentNullException(nameof(inputProtocolFactory));
+ OutputProtocolFactory = outputProtocolFactory ?? throw new ArgumentNullException(nameof(outputProtocolFactory));
+ Logger = logger; // null is absolutely legal
+ }
+
+ public void SetEventHandler(TServerEventHandler seh)
+ {
+ ServerEventHandler = seh;
+ }
+
+ public TServerEventHandler GetEventHandler()
+ {
+ return ServerEventHandler;
+ }
+
+ // Log delegation? deprecated, use ILogger
+ protected void LogError( string msg)
+ {
+ if (Logger != null)
+ Logger.LogError(msg);
+ }
+
+ public abstract void Stop();
+
+ public virtual void Start()
+ {
+ // do nothing
+ }
+
+ public virtual async Task ServeAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Server/TServerEventHandler.cs b/lib/netstd/Thrift/Server/TServerEventHandler.cs
new file mode 100644
index 0000000..0c31bf6
--- /dev/null
+++ b/lib/netstd/Thrift/Server/TServerEventHandler.cs
@@ -0,0 +1,54 @@
+// 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.
+
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol;
+using Thrift.Transport;
+
+namespace Thrift.Server
+{
+ //TODO: replacement by event?
+
+ /// <summary>
+ /// Interface implemented by server users to handle events from the server
+ /// </summary>
+ // ReSharper disable once InconsistentNaming
+ public interface TServerEventHandler
+ {
+ /// <summary>
+ /// Called before the server begins */
+ /// </summary>
+ Task PreServeAsync(CancellationToken cancellationToken);
+
+ /// <summary>
+ /// Called when a new client has connected and is about to being processing */
+ /// </summary>
+ Task<object> CreateContextAsync(TProtocol input, TProtocol output, CancellationToken cancellationToken);
+
+ /// <summary>
+ /// Called when a client has finished request-handling to delete server context */
+ /// </summary>
+ Task DeleteContextAsync(object serverContext, TProtocol input, TProtocol output,
+ CancellationToken cancellationToken);
+
+ /// <summary>
+ /// Called when a client is about to call the processor */
+ /// </summary>
+ Task ProcessContextAsync(object serverContext, TTransport transport, CancellationToken cancellationToken);
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Server/TSimpleAsyncServer.cs b/lib/netstd/Thrift/Server/TSimpleAsyncServer.cs
new file mode 100644
index 0000000..bdaa348
--- /dev/null
+++ b/lib/netstd/Thrift/Server/TSimpleAsyncServer.cs
@@ -0,0 +1,230 @@
+// 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.
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Thrift.Protocol;
+using Thrift.Processor;
+using Thrift.Transport;
+
+namespace Thrift.Server
+{
+ //TODO: unhandled exceptions, etc.
+
+ // ReSharper disable once InconsistentNaming
+ public class TSimpleAsyncServer : TServer
+ {
+ private readonly int _clientWaitingDelay;
+ private volatile Task _serverTask;
+
+ public TSimpleAsyncServer(ITProcessorFactory itProcessorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory,
+ TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ ILogger logger,
+ int clientWaitingDelay = 10)
+ : base(itProcessorFactory,
+ serverTransport,
+ inputTransportFactory,
+ outputTransportFactory,
+ inputProtocolFactory,
+ outputProtocolFactory,
+ logger)
+ {
+ _clientWaitingDelay = clientWaitingDelay;
+ }
+
+ public TSimpleAsyncServer(ITProcessorFactory itProcessorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory,
+ TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ ILoggerFactory loggerFactory,
+ int clientWaitingDelay = 10)
+ : this(itProcessorFactory,
+ serverTransport,
+ inputTransportFactory,
+ outputTransportFactory,
+ inputProtocolFactory,
+ outputProtocolFactory,
+ loggerFactory.CreateLogger<TSimpleAsyncServer>())
+ {
+ }
+
+ public TSimpleAsyncServer(ITAsyncProcessor processor,
+ TServerTransport serverTransport,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ ILoggerFactory loggerFactory,
+ int clientWaitingDelay = 10)
+ : this(new TSingletonProcessorFactory(processor),
+ serverTransport,
+ null, // defaults to TTransportFactory()
+ null, // defaults to TTransportFactory()
+ inputProtocolFactory,
+ outputProtocolFactory,
+ loggerFactory.CreateLogger(nameof(TSimpleAsyncServer)),
+ clientWaitingDelay)
+ {
+ }
+
+ public override async Task ServeAsync(CancellationToken cancellationToken)
+ {
+ try
+ {
+ // cancelation token
+ _serverTask = Task.Factory.StartNew(() => StartListening(cancellationToken), TaskCreationOptions.LongRunning);
+ await _serverTask;
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError(ex.ToString());
+ }
+ }
+
+ private async Task StartListening(CancellationToken cancellationToken)
+ {
+ ServerTransport.Listen();
+
+ Logger.LogTrace("Started listening at server");
+
+ if (ServerEventHandler != null)
+ {
+ await ServerEventHandler.PreServeAsync(cancellationToken);
+ }
+
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ if (ServerTransport.IsClientPending())
+ {
+ Logger.LogTrace("Waiting for client connection");
+
+ try
+ {
+ var client = await ServerTransport.AcceptAsync(cancellationToken);
+ await Task.Factory.StartNew(() => Execute(client, cancellationToken), cancellationToken);
+ }
+ catch (TTransportException ttx)
+ {
+ Logger.LogTrace($"Transport exception: {ttx}");
+
+ if (ttx.Type != TTransportException.ExceptionType.Interrupted)
+ {
+ Logger.LogError(ttx.ToString());
+ }
+ }
+ }
+ else
+ {
+ try
+ {
+ await Task.Delay(TimeSpan.FromMilliseconds(_clientWaitingDelay), cancellationToken);
+ }
+ catch (TaskCanceledException) { }
+ }
+ }
+
+ ServerTransport.Close();
+
+ Logger.LogTrace("Completed listening at server");
+ }
+
+ public override void Stop()
+ {
+ }
+
+ private async Task Execute(TTransport client, CancellationToken cancellationToken)
+ {
+ Logger.LogTrace("Started client request processing");
+
+ var processor = ProcessorFactory.GetAsyncProcessor(client, this);
+
+ TTransport inputTransport = null;
+ TTransport outputTransport = null;
+ TProtocol inputProtocol = null;
+ TProtocol outputProtocol = null;
+ object connectionContext = null;
+
+ try
+ {
+ try
+ {
+ inputTransport = InputTransportFactory.GetTransport(client);
+ outputTransport = OutputTransportFactory.GetTransport(client);
+ inputProtocol = InputProtocolFactory.GetProtocol(inputTransport);
+ outputProtocol = OutputProtocolFactory.GetProtocol(outputTransport);
+
+ if (ServerEventHandler != null)
+ {
+ connectionContext = await ServerEventHandler.CreateContextAsync(inputProtocol, outputProtocol, cancellationToken);
+ }
+
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ if (!await inputTransport.PeekAsync(cancellationToken))
+ {
+ break;
+ }
+
+ if (ServerEventHandler != null)
+ {
+ await ServerEventHandler.ProcessContextAsync(connectionContext, inputTransport, cancellationToken);
+ }
+
+ if (!await processor.ProcessAsync(inputProtocol, outputProtocol, cancellationToken))
+ {
+ break;
+ }
+ }
+ }
+ catch (TTransportException ttx)
+ {
+ Logger.LogTrace($"Transport exception: {ttx}");
+ }
+ catch (Exception x)
+ {
+ Logger.LogError($"Error: {x}");
+ }
+
+ if (ServerEventHandler != null)
+ {
+ await ServerEventHandler.DeleteContextAsync(connectionContext, inputProtocol, outputProtocol, cancellationToken);
+ }
+
+ }
+ finally
+ {
+ //Close transports
+ inputTransport?.Close();
+ outputTransport?.Close();
+
+ // disposable stuff should be disposed
+ inputProtocol?.Dispose();
+ outputProtocol?.Dispose();
+ inputTransport?.Dispose();
+ outputTransport?.Dispose();
+ }
+
+ Logger.LogTrace("Completed client request processing");
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Server/TThreadPoolAsyncServer.cs b/lib/netstd/Thrift/Server/TThreadPoolAsyncServer.cs
new file mode 100644
index 0000000..20e659d
--- /dev/null
+++ b/lib/netstd/Thrift/Server/TThreadPoolAsyncServer.cs
@@ -0,0 +1,297 @@
+/**
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System;
+using System.Threading;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Processor;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+
+namespace Thrift.Server
+{
+ /// <summary>
+ /// Server that uses C# built-in ThreadPool to spawn threads when handling requests.
+ /// </summary>
+ public class TThreadPoolAsyncServer : TServer
+ {
+ private const int DEFAULT_MIN_THREADS = -1; // use .NET ThreadPool defaults
+ private const int DEFAULT_MAX_THREADS = -1; // use .NET ThreadPool defaults
+ private volatile bool stop = false;
+
+ private CancellationToken ServerCancellationToken;
+
+ public struct Configuration
+ {
+ public int MinWorkerThreads;
+ public int MaxWorkerThreads;
+ public int MinIOThreads;
+ public int MaxIOThreads;
+
+ public Configuration(int min = DEFAULT_MIN_THREADS, int max = DEFAULT_MAX_THREADS)
+ {
+ MinWorkerThreads = min;
+ MaxWorkerThreads = max;
+ MinIOThreads = min;
+ MaxIOThreads = max;
+ }
+
+ public Configuration(int minWork, int maxWork, int minIO, int maxIO)
+ {
+ MinWorkerThreads = minWork;
+ MaxWorkerThreads = maxWork;
+ MinIOThreads = minIO;
+ MaxIOThreads = maxIO;
+ }
+ }
+
+ public TThreadPoolAsyncServer(ITAsyncProcessor processor, TServerTransport serverTransport, ILogger logger = null)
+ : this(new TSingletonProcessorFactory(processor), serverTransport,
+ null, null, // defaults to TTransportFactory()
+ new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
+ new Configuration(), logger)
+ {
+ }
+
+ public TThreadPoolAsyncServer(ITAsyncProcessor processor,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ : this(new TSingletonProcessorFactory(processor), serverTransport,
+ transportFactory, transportFactory,
+ protocolFactory, protocolFactory,
+ new Configuration())
+ {
+ }
+
+ public TThreadPoolAsyncServer(ITProcessorFactory processorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory transportFactory,
+ TProtocolFactory protocolFactory)
+ : this(processorFactory, serverTransport,
+ transportFactory, transportFactory,
+ protocolFactory, protocolFactory,
+ new Configuration())
+ {
+ }
+
+ public TThreadPoolAsyncServer(ITProcessorFactory processorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory,
+ TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ int minThreadPoolThreads, int maxThreadPoolThreads, ILogger logger= null)
+ : this(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory,
+ inputProtocolFactory, outputProtocolFactory,
+ new Configuration(minThreadPoolThreads, maxThreadPoolThreads),
+ logger)
+ {
+ }
+
+ public TThreadPoolAsyncServer(ITProcessorFactory processorFactory,
+ TServerTransport serverTransport,
+ TTransportFactory inputTransportFactory,
+ TTransportFactory outputTransportFactory,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ Configuration threadConfig,
+ ILogger logger = null)
+ : base(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory,
+ inputProtocolFactory, outputProtocolFactory, logger)
+ {
+ lock (typeof(TThreadPoolAsyncServer))
+ {
+ if ((threadConfig.MaxWorkerThreads > 0) || (threadConfig.MaxIOThreads > 0))
+ {
+ int work, comm;
+ ThreadPool.GetMaxThreads(out work, out comm);
+ if (threadConfig.MaxWorkerThreads > 0)
+ work = threadConfig.MaxWorkerThreads;
+ if (threadConfig.MaxIOThreads > 0)
+ comm = threadConfig.MaxIOThreads;
+ if (!ThreadPool.SetMaxThreads(work, comm))
+ throw new Exception("Error: could not SetMaxThreads in ThreadPool");
+ }
+
+ if ((threadConfig.MinWorkerThreads > 0) || (threadConfig.MinIOThreads > 0))
+ {
+ int work, comm;
+ ThreadPool.GetMinThreads(out work, out comm);
+ if (threadConfig.MinWorkerThreads > 0)
+ work = threadConfig.MinWorkerThreads;
+ if (threadConfig.MinIOThreads > 0)
+ comm = threadConfig.MinIOThreads;
+ if (!ThreadPool.SetMinThreads(work, comm))
+ throw new Exception("Error: could not SetMinThreads in ThreadPool");
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// Use new ThreadPool thread for each new client connection.
+ /// </summary>
+ public override async Task ServeAsync(CancellationToken cancellationToken)
+ {
+ ServerCancellationToken = cancellationToken;
+ try
+ {
+ try
+ {
+ ServerTransport.Listen();
+ }
+ catch (TTransportException ttx)
+ {
+ LogError("Error, could not listen on ServerTransport: " + ttx);
+ return;
+ }
+
+ //Fire the preServe server event when server is up but before any client connections
+ if (ServerEventHandler != null)
+ await ServerEventHandler.PreServeAsync(cancellationToken);
+
+ while (!stop)
+ {
+ int failureCount = 0;
+ try
+ {
+ TTransport client = await ServerTransport.AcceptAsync(cancellationToken);
+ ThreadPool.QueueUserWorkItem(this.Execute, client);
+ }
+ catch (TTransportException ttx)
+ {
+ if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
+ {
+ ++failureCount;
+ LogError(ttx.ToString());
+ }
+
+ }
+ }
+
+ if (stop)
+ {
+ try
+ {
+ ServerTransport.Close();
+ }
+ catch (TTransportException ttx)
+ {
+ LogError("TServerTransport failed on close: " + ttx.Message);
+ }
+ stop = false;
+ }
+
+ }
+ finally
+ {
+ ServerCancellationToken = default(CancellationToken);
+ }
+ }
+
+ /// <summary>
+ /// Loops on processing a client forever
+ /// threadContext will be a TTransport instance
+ /// </summary>
+ /// <param name="threadContext"></param>
+ private void Execute(object threadContext)
+ {
+ var cancellationToken = ServerCancellationToken;
+
+ using (TTransport client = (TTransport)threadContext)
+ {
+ ITAsyncProcessor processor = ProcessorFactory.GetAsyncProcessor(client, this);
+ TTransport inputTransport = null;
+ TTransport outputTransport = null;
+ TProtocol inputProtocol = null;
+ TProtocol outputProtocol = null;
+ object connectionContext = null;
+ try
+ {
+ try
+ {
+ inputTransport = InputTransportFactory.GetTransport(client);
+ outputTransport = OutputTransportFactory.GetTransport(client);
+ inputProtocol = InputProtocolFactory.GetProtocol(inputTransport);
+ outputProtocol = OutputProtocolFactory.GetProtocol(outputTransport);
+
+ //Recover event handler (if any) and fire createContext server event when a client connects
+ if (ServerEventHandler != null)
+ connectionContext = ServerEventHandler.CreateContextAsync(inputProtocol, outputProtocol, cancellationToken).Result;
+
+ //Process client requests until client disconnects
+ while (!stop)
+ {
+ if (! inputTransport.PeekAsync(cancellationToken).Result)
+ break;
+
+ //Fire processContext server event
+ //N.B. This is the pattern implemented in C++ and the event fires provisionally.
+ //That is to say it may be many minutes between the event firing and the client request
+ //actually arriving or the client may hang up without ever makeing a request.
+ if (ServerEventHandler != null)
+ ServerEventHandler.ProcessContextAsync(connectionContext, inputTransport, cancellationToken).Wait();
+ //Process client request (blocks until transport is readable)
+ if (!processor.ProcessAsync(inputProtocol, outputProtocol, cancellationToken).Result)
+ break;
+ }
+ }
+ catch (TTransportException)
+ {
+ //Usually a client disconnect, expected
+ }
+ catch (Exception x)
+ {
+ //Unexpected
+ LogError("Error: " + x);
+ }
+
+ //Fire deleteContext server event after client disconnects
+ if (ServerEventHandler != null)
+ ServerEventHandler.DeleteContextAsync(connectionContext, inputProtocol, outputProtocol, cancellationToken).Wait();
+
+ }
+ finally
+ {
+ //Close transports
+ inputTransport?.Close();
+ outputTransport?.Close();
+
+ // disposable stuff should be disposed
+ inputProtocol?.Dispose();
+ outputProtocol?.Dispose();
+ inputTransport?.Dispose();
+ outputTransport?.Dispose();
+ }
+ }
+ }
+
+ public override void Stop()
+ {
+ stop = true;
+ ServerTransport?.Close();
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/TApplicationException.cs b/lib/netstd/Thrift/TApplicationException.cs
new file mode 100644
index 0000000..9c86898
--- /dev/null
+++ b/lib/netstd/Thrift/TApplicationException.cs
@@ -0,0 +1,150 @@
+// 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.
+
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol;
+using Thrift.Protocol.Entities;
+using Thrift.Protocol.Utilities;
+
+namespace Thrift
+{
+ // ReSharper disable once InconsistentNaming
+ public class TApplicationException : TException
+ {
+ public enum ExceptionType
+ {
+ Unknown,
+ UnknownMethod,
+ InvalidMessageType,
+ WrongMethodName,
+ BadSequenceId,
+ MissingResult,
+ InternalError,
+ ProtocolError,
+ InvalidTransform,
+ InvalidProtocol,
+ UnsupportedClientType
+ }
+
+ private const int MessageTypeFieldId = 1;
+ private const int ExTypeFieldId = 2;
+
+ public ExceptionType Type { get; private set; }
+
+ public TApplicationException()
+ {
+ }
+
+ public TApplicationException(ExceptionType type)
+ {
+ Type = type;
+ }
+
+ public TApplicationException(ExceptionType type, string message)
+ : base(message, null) // TApplicationException is serializable, but we never serialize InnerException
+ {
+ Type = type;
+ }
+
+ public static async Task<TApplicationException> ReadAsync(TProtocol inputProtocol, CancellationToken cancellationToken)
+ {
+ string message = null;
+ var type = ExceptionType.Unknown;
+
+ await inputProtocol.ReadStructBeginAsync(cancellationToken);
+ while (true)
+ {
+ var field = await inputProtocol.ReadFieldBeginAsync(cancellationToken);
+ if (field.Type == TType.Stop)
+ {
+ break;
+ }
+
+ switch (field.ID)
+ {
+ case MessageTypeFieldId:
+ if (field.Type == TType.String)
+ {
+ message = await inputProtocol.ReadStringAsync(cancellationToken);
+ }
+ else
+ {
+ await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
+ }
+ break;
+ case ExTypeFieldId:
+ if (field.Type == TType.I32)
+ {
+ type = (ExceptionType) await inputProtocol.ReadI32Async(cancellationToken);
+ }
+ else
+ {
+ await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
+ }
+ break;
+ default:
+ await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
+ break;
+ }
+
+ await inputProtocol.ReadFieldEndAsync(cancellationToken);
+ }
+
+ await inputProtocol.ReadStructEndAsync(cancellationToken);
+
+ return new TApplicationException(type, message);
+ }
+
+ public async Task WriteAsync(TProtocol outputProtocol, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+
+ const string messageTypeFieldName = "message";
+ const string exTypeFieldName = "exType";
+ const string structApplicationExceptionName = "TApplicationException";
+
+ var struc = new TStruct(structApplicationExceptionName);
+ var field = new TField();
+
+ await outputProtocol.WriteStructBeginAsync(struc, cancellationToken);
+
+ if (!string.IsNullOrEmpty(Message))
+ {
+ field.Name = messageTypeFieldName;
+ field.Type = TType.String;
+ field.ID = MessageTypeFieldId;
+ await outputProtocol.WriteFieldBeginAsync(field, cancellationToken);
+ await outputProtocol.WriteStringAsync(Message, cancellationToken);
+ await outputProtocol.WriteFieldEndAsync(cancellationToken);
+ }
+
+ field.Name = exTypeFieldName;
+ field.Type = TType.I32;
+ field.ID = ExTypeFieldId;
+
+ await outputProtocol.WriteFieldBeginAsync(field, cancellationToken);
+ await outputProtocol.WriteI32Async((int) Type, cancellationToken);
+ await outputProtocol.WriteFieldEndAsync(cancellationToken);
+ await outputProtocol.WriteFieldStopAsync(cancellationToken);
+ await outputProtocol.WriteStructEndAsync(cancellationToken);
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/TBaseClient.cs b/lib/netstd/Thrift/TBaseClient.cs
new file mode 100644
index 0000000..0edac0f
--- /dev/null
+++ b/lib/netstd/Thrift/TBaseClient.cs
@@ -0,0 +1,91 @@
+// 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.
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Protocol;
+
+namespace Thrift
+{
+ // ReSharper disable once InconsistentNaming
+ /// <summary>
+ /// TBaseClient.
+ /// Base client for generated clients.
+ /// Do not change this class without checking generated code (namings, etc.)
+ /// </summary>
+ public abstract class TBaseClient
+ {
+ private readonly TProtocol _inputProtocol;
+ private readonly TProtocol _outputProtocol;
+ private bool _isDisposed;
+ private int _seqId;
+ public readonly Guid ClientId = Guid.NewGuid();
+
+ protected TBaseClient(TProtocol inputProtocol, TProtocol outputProtocol)
+ {
+ _inputProtocol = inputProtocol ?? throw new ArgumentNullException(nameof(inputProtocol));
+ _outputProtocol = outputProtocol ?? throw new ArgumentNullException(nameof(outputProtocol));
+ }
+
+ public TProtocol InputProtocol => _inputProtocol;
+
+ public TProtocol OutputProtocol => _outputProtocol;
+
+ public int SeqId
+ {
+ get { return ++_seqId; }
+ }
+
+ public virtual async Task OpenTransportAsync()
+ {
+ await OpenTransportAsync(CancellationToken.None);
+ }
+
+ public virtual async Task OpenTransportAsync(CancellationToken cancellationToken)
+ {
+ if (!_inputProtocol.Transport.IsOpen)
+ {
+ await _inputProtocol.Transport.OpenAsync(cancellationToken);
+ }
+
+ if (!_inputProtocol.Transport.IsOpen)
+ {
+ await _outputProtocol.Transport.OpenAsync(cancellationToken);
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_isDisposed)
+ {
+ if (disposing)
+ {
+ _inputProtocol?.Dispose();
+ _outputProtocol?.Dispose();
+ }
+ }
+
+ _isDisposed = true;
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/TException.cs b/lib/netstd/Thrift/TException.cs
new file mode 100644
index 0000000..43e7054
--- /dev/null
+++ b/lib/netstd/Thrift/TException.cs
@@ -0,0 +1,34 @@
+// 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.
+
+using System;
+
+namespace Thrift
+{
+ // ReSharper disable once InconsistentNaming
+ public class TException : Exception
+ {
+ public TException()
+ {
+ }
+
+ public TException(string message, Exception inner)
+ : base(message, inner)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Thrift.csproj b/lib/netstd/Thrift/Thrift.csproj
new file mode 100644
index 0000000..d093803
--- /dev/null
+++ b/lib/netstd/Thrift/Thrift.csproj
@@ -0,0 +1,54 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <!--
+ 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.
+ -->
+
+ <PropertyGroup>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ <AssemblyName>Thrift</AssemblyName>
+ <PackageId>Thrift</PackageId>
+ <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+ <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
+ <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
+ <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ <GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
+ <GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
+ <PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
+ <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
+ <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
+ <PackageReference Include="System.IO.Pipes" Version="[4.3,)" />
+ <PackageReference Include="System.IO.Pipes.AccessControl" Version="4.5.1" />
+ <PackageReference Include="System.Net.Http.WinHttpHandler" Version="4.5.2" />
+ <PackageReference Include="System.Net.NameResolution" Version="[4.3,)" />
+ <PackageReference Include="System.Net.Requests" Version="[4.3,)" />
+ <PackageReference Include="System.Net.Security" Version="4.3.2" />
+ </ItemGroup>
+
+</Project>
diff --git a/lib/netstd/Thrift/Transport/Client/THttpTransport.cs b/lib/netstd/Thrift/Transport/Client/THttpTransport.cs
new file mode 100644
index 0000000..627c93d
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/Client/THttpTransport.cs
@@ -0,0 +1,232 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Thrift.Transport.Client
+{
+ // ReSharper disable once InconsistentNaming
+ public class THttpTransport : TTransport
+ {
+ private readonly X509Certificate[] _certificates;
+ private readonly Uri _uri;
+
+ // Timeouts in milliseconds
+ private int _connectTimeout = 30000;
+ private HttpClient _httpClient;
+ private Stream _inputStream;
+
+ private bool _isDisposed;
+ private MemoryStream _outputStream = new MemoryStream();
+
+ public THttpTransport(Uri u, IDictionary<string, string> customHeaders = null, string userAgent = null)
+ : this(u, Enumerable.Empty<X509Certificate>(), customHeaders, userAgent)
+ {
+ }
+
+ public THttpTransport(Uri u, IEnumerable<X509Certificate> certificates,
+ IDictionary<string, string> customHeaders, string userAgent = null)
+ {
+ _uri = u;
+ _certificates = (certificates ?? Enumerable.Empty<X509Certificate>()).ToArray();
+ CustomHeaders = customHeaders;
+
+ if (!string.IsNullOrEmpty(userAgent))
+ UserAgent = userAgent;
+
+ // due to current bug with performance of Dispose in netcore https://github.com/dotnet/corefx/issues/8809
+ // this can be switched to default way (create client->use->dispose per flush) later
+ _httpClient = CreateClient();
+ }
+
+ // According to RFC 2616 section 3.8, the "User-Agent" header may not carry a version number
+ public readonly string UserAgent = "Thrift netstd THttpClient";
+
+ public IDictionary<string, string> CustomHeaders { get; }
+
+ public int ConnectTimeout
+ {
+ set { _connectTimeout = value; }
+ }
+
+ public override bool IsOpen => true;
+
+ public override async Task OpenAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override void Close()
+ {
+ if (_inputStream != null)
+ {
+ _inputStream.Dispose();
+ _inputStream = null;
+ }
+
+ if (_outputStream != null)
+ {
+ _outputStream.Dispose();
+ _outputStream = null;
+ }
+
+ if (_httpClient != null)
+ {
+ _httpClient.Dispose();
+ _httpClient = null;
+ }
+ }
+
+ public override async Task<int> ReadAsync(byte[] buffer, int offset, int length,
+ CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<int>(cancellationToken);
+ }
+
+ if (_inputStream == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No request has been sent");
+ }
+
+ try
+ {
+ var ret = await _inputStream.ReadAsync(buffer, offset, length, cancellationToken);
+
+ if (ret == -1)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.EndOfFile, "No more data available");
+ }
+
+ return ret;
+ }
+ catch (IOException iox)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString());
+ }
+ }
+
+ public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+
+ await _outputStream.WriteAsync(buffer, offset, length, cancellationToken);
+ }
+
+ private HttpClient CreateClient()
+ {
+ var handler = new HttpClientHandler();
+ handler.ClientCertificates.AddRange(_certificates);
+
+ var httpClient = new HttpClient(handler);
+
+ if (_connectTimeout > 0)
+ {
+ httpClient.Timeout = TimeSpan.FromSeconds(_connectTimeout);
+ }
+
+ httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-thrift"));
+ httpClient.DefaultRequestHeaders.UserAgent.TryParseAdd(UserAgent);
+
+ if (CustomHeaders != null)
+ {
+ foreach (var item in CustomHeaders)
+ {
+ httpClient.DefaultRequestHeaders.Add(item.Key, item.Value);
+ }
+ }
+
+ return httpClient;
+ }
+
+ public override async Task FlushAsync(CancellationToken cancellationToken)
+ {
+ try
+ {
+ try
+ {
+ if (_outputStream.CanSeek)
+ {
+ _outputStream.Seek(0, SeekOrigin.Begin);
+ }
+
+ using (var outStream = new StreamContent(_outputStream))
+ {
+ var msg = await _httpClient.PostAsync(_uri, outStream, cancellationToken);
+
+ msg.EnsureSuccessStatusCode();
+
+ if (_inputStream != null)
+ {
+ _inputStream.Dispose();
+ _inputStream = null;
+ }
+
+ _inputStream = await msg.Content.ReadAsStreamAsync();
+ if (_inputStream.CanSeek)
+ {
+ _inputStream.Seek(0, SeekOrigin.Begin);
+ }
+ }
+ }
+ catch (IOException iox)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, iox.ToString());
+ }
+ catch (HttpRequestException wx)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown,
+ "Couldn't connect to server: " + wx);
+ }
+ }
+ finally
+ {
+ _outputStream = new MemoryStream();
+ }
+ }
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_isDisposed)
+ {
+ if (disposing)
+ {
+ _inputStream?.Dispose();
+ _outputStream?.Dispose();
+ _httpClient?.Dispose();
+ }
+ }
+ _isDisposed = true;
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Transport/Client/TMemoryBufferTransport.cs b/lib/netstd/Thrift/Transport/Client/TMemoryBufferTransport.cs
new file mode 100644
index 0000000..75529d1
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/Client/TMemoryBufferTransport.cs
@@ -0,0 +1,97 @@
+// 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.
+
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Thrift.Transport.Client
+{
+ // ReSharper disable once InconsistentNaming
+ public class TMemoryBufferTransport : TTransport
+ {
+ private readonly MemoryStream _byteStream;
+ private bool _isDisposed;
+
+ public TMemoryBufferTransport()
+ {
+ _byteStream = new MemoryStream();
+ }
+
+ public TMemoryBufferTransport(byte[] buf)
+ {
+ _byteStream = new MemoryStream(buf);
+ }
+
+ public override bool IsOpen => true;
+
+ public override async Task OpenAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override void Close()
+ {
+ /** do nothing **/
+ }
+
+ public override async Task<int> ReadAsync(byte[] buffer, int offset, int length,
+ CancellationToken cancellationToken)
+ {
+ return await _byteStream.ReadAsync(buffer, offset, length, cancellationToken);
+ }
+
+ public override async Task WriteAsync(byte[] buffer, CancellationToken cancellationToken)
+ {
+ await _byteStream.WriteAsync(buffer, 0, buffer.Length, cancellationToken);
+ }
+
+ public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
+ {
+ await _byteStream.WriteAsync(buffer, offset, length, cancellationToken);
+ }
+
+ public override async Task FlushAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public byte[] GetBuffer()
+ {
+ return _byteStream.ToArray();
+ }
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_isDisposed)
+ {
+ if (disposing)
+ {
+ _byteStream?.Dispose();
+ }
+ }
+ _isDisposed = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs b/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs
new file mode 100644
index 0000000..b78c791
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs
@@ -0,0 +1,98 @@
+// 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.
+
+using System.IO.Pipes;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Thrift.Transport.Client
+{
+ // ReSharper disable once InconsistentNaming
+ public class TNamedPipeTransport : TTransport
+ {
+ private NamedPipeClientStream _client;
+ private int ConnectTimeout;
+
+ public TNamedPipeTransport(string pipe, int timeout = Timeout.Infinite)
+ : this(".", pipe, timeout)
+ {
+ }
+
+ public TNamedPipeTransport(string server, string pipe, int timeout = Timeout.Infinite)
+ {
+ var serverName = string.IsNullOrWhiteSpace(server) ? server : ".";
+ ConnectTimeout = (timeout > 0) ? timeout : Timeout.Infinite;
+
+ _client = new NamedPipeClientStream(serverName, pipe, PipeDirection.InOut, PipeOptions.None);
+ }
+
+ public override bool IsOpen => _client != null && _client.IsConnected;
+
+ public override async Task OpenAsync(CancellationToken cancellationToken)
+ {
+ if (IsOpen)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen);
+ }
+
+ await _client.ConnectAsync( ConnectTimeout, cancellationToken);
+ }
+
+ public override void Close()
+ {
+ if (_client != null)
+ {
+ _client.Dispose();
+ _client = null;
+ }
+ }
+
+ public override async Task<int> ReadAsync(byte[] buffer, int offset, int length,
+ CancellationToken cancellationToken)
+ {
+ if (_client == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ return await _client.ReadAsync(buffer, offset, length, cancellationToken);
+ }
+
+ public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
+ {
+ if (_client == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ await _client.WriteAsync(buffer, offset, length, cancellationToken);
+ }
+
+ public override async Task FlushAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ _client.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Transport/Client/TSocketTransport.cs b/lib/netstd/Thrift/Transport/Client/TSocketTransport.cs
new file mode 100644
index 0000000..00da045
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/Client/TSocketTransport.cs
@@ -0,0 +1,162 @@
+// 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.
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Thrift.Transport.Client
+{
+ // ReSharper disable once InconsistentNaming
+ public class TSocketTransport : TStreamTransport
+ {
+ private bool _isDisposed;
+
+
+ public TSocketTransport(TcpClient client)
+ {
+ TcpClient = client ?? throw new ArgumentNullException(nameof(client));
+ SetInputOutputStream();
+ }
+
+ public TSocketTransport(IPAddress host, int port)
+ : this(host, port, 0)
+ {
+ }
+
+ public TSocketTransport(IPAddress host, int port, int timeout)
+ {
+ Host = host;
+ Port = port;
+
+ TcpClient = new TcpClient();
+ TcpClient.ReceiveTimeout = TcpClient.SendTimeout = timeout;
+ TcpClient.Client.NoDelay = true;
+ SetInputOutputStream();
+ }
+
+ public TSocketTransport(string host, int port, int timeout = 0)
+ {
+ try
+ {
+ var entry = Dns.GetHostEntry(host);
+ if (entry.AddressList.Length == 0)
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, "unable to resolve host name");
+
+ var addr = entry.AddressList[0];
+ Host = new IPAddress(addr.GetAddressBytes(), addr.ScopeId);
+ Port = port;
+
+ TcpClient = new TcpClient(host, port);
+ TcpClient.ReceiveTimeout = TcpClient.SendTimeout = timeout;
+ TcpClient.Client.NoDelay = true;
+ SetInputOutputStream();
+ }
+ catch (SocketException e)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, e.Message, e);
+ }
+ }
+
+ private void SetInputOutputStream()
+ {
+ if (IsOpen)
+ {
+ InputStream = TcpClient.GetStream();
+ OutputStream = TcpClient.GetStream();
+ }
+ }
+
+ public TcpClient TcpClient { get; private set; }
+ public IPAddress Host { get; }
+ public int Port { get; }
+
+ public int Timeout
+ {
+ set
+ {
+ if (TcpClient != null)
+ {
+ TcpClient.ReceiveTimeout = TcpClient.SendTimeout = value;
+ }
+ }
+ }
+
+ public override bool IsOpen
+ {
+ get
+ {
+ return (TcpClient != null) && TcpClient.Connected;
+ }
+ }
+
+ public override async Task OpenAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+
+ if (IsOpen)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
+ }
+
+ if (Port <= 0)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port");
+ }
+
+ if (TcpClient == null)
+ {
+ throw new InvalidOperationException("Invalid or not initialized tcp client");
+ }
+
+ await TcpClient.ConnectAsync(Host, Port);
+ SetInputOutputStream();
+ }
+
+ public override void Close()
+ {
+ base.Close();
+
+ if (TcpClient != null)
+ {
+ TcpClient.Dispose();
+ TcpClient = null;
+ }
+ }
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_isDisposed)
+ {
+ if (disposing)
+ {
+ TcpClient?.Dispose();
+
+ base.Dispose(disposing);
+ }
+ }
+ _isDisposed = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs b/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs
new file mode 100644
index 0000000..9b03533
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs
@@ -0,0 +1,110 @@
+// 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.
+
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Thrift.Transport.Client
+{
+ // ReSharper disable once InconsistentNaming
+ public class TStreamTransport : TTransport
+ {
+ private bool _isDisposed;
+
+ protected TStreamTransport()
+ {
+ }
+
+ public TStreamTransport(Stream inputStream, Stream outputStream)
+ {
+ InputStream = inputStream;
+ OutputStream = outputStream;
+ }
+
+ protected Stream OutputStream { get; set; }
+
+ protected Stream InputStream { get; set; }
+
+ public override bool IsOpen => true;
+
+ public override async Task OpenAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override void Close()
+ {
+ if (InputStream != null)
+ {
+ InputStream.Dispose();
+ InputStream = null;
+ }
+
+ if (OutputStream != null)
+ {
+ OutputStream.Dispose();
+ OutputStream = null;
+ }
+ }
+
+ public override async Task<int> ReadAsync(byte[] buffer, int offset, int length,
+ CancellationToken cancellationToken)
+ {
+ if (InputStream == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen,
+ "Cannot read from null inputstream");
+ }
+
+ return await InputStream.ReadAsync(buffer, offset, length, cancellationToken);
+ }
+
+ public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
+ {
+ if (OutputStream == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen,
+ "Cannot write to null outputstream");
+ }
+
+ await OutputStream.WriteAsync(buffer, offset, length, cancellationToken);
+ }
+
+ public override async Task FlushAsync(CancellationToken cancellationToken)
+ {
+ await OutputStream.FlushAsync(cancellationToken);
+ }
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_isDisposed)
+ {
+ if (disposing)
+ {
+ InputStream?.Dispose();
+ OutputStream?.Dispose();
+ }
+ }
+ _isDisposed = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs b/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs
new file mode 100644
index 0000000..9295bb0
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs
@@ -0,0 +1,267 @@
+// 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.
+
+using System;
+using System.Net;
+using System.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Thrift.Transport.Client
+{
+ //TODO: check for correct work
+
+ // ReSharper disable once InconsistentNaming
+ public class TTlsSocketTransport : TStreamTransport
+ {
+ private readonly X509Certificate2 _certificate;
+ private readonly RemoteCertificateValidationCallback _certValidator;
+ private readonly IPAddress _host;
+ private readonly bool _isServer;
+ private readonly LocalCertificateSelectionCallback _localCertificateSelectionCallback;
+ private readonly int _port;
+ private readonly SslProtocols _sslProtocols;
+ private TcpClient _client;
+ private SslStream _secureStream;
+ private int _timeout;
+
+ public TTlsSocketTransport(TcpClient client, X509Certificate2 certificate, bool isServer = false,
+ RemoteCertificateValidationCallback certValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ SslProtocols sslProtocols = SslProtocols.Tls12)
+ {
+ _client = client;
+ _certificate = certificate;
+ _certValidator = certValidator;
+ _localCertificateSelectionCallback = localCertificateSelectionCallback;
+ _sslProtocols = sslProtocols;
+ _isServer = isServer;
+
+ if (isServer && certificate == null)
+ {
+ throw new ArgumentException("TTlsSocketTransport needs certificate to be used for server",
+ nameof(certificate));
+ }
+
+ if (IsOpen)
+ {
+ InputStream = client.GetStream();
+ OutputStream = client.GetStream();
+ }
+ }
+
+ public TTlsSocketTransport(IPAddress host, int port, string certificatePath,
+ RemoteCertificateValidationCallback certValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ SslProtocols sslProtocols = SslProtocols.Tls12)
+ : this(host, port, 0,
+ new X509Certificate2(certificatePath),
+ certValidator,
+ localCertificateSelectionCallback,
+ sslProtocols)
+ {
+ }
+
+ public TTlsSocketTransport(IPAddress host, int port,
+ X509Certificate2 certificate = null,
+ RemoteCertificateValidationCallback certValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ SslProtocols sslProtocols = SslProtocols.Tls12)
+ : this(host, port, 0,
+ certificate,
+ certValidator,
+ localCertificateSelectionCallback,
+ sslProtocols)
+ {
+ }
+
+ public TTlsSocketTransport(IPAddress host, int port, int timeout,
+ X509Certificate2 certificate,
+ RemoteCertificateValidationCallback certValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ SslProtocols sslProtocols = SslProtocols.Tls12)
+ {
+ _host = host;
+ _port = port;
+ _timeout = timeout;
+ _certificate = certificate;
+ _certValidator = certValidator;
+ _localCertificateSelectionCallback = localCertificateSelectionCallback;
+ _sslProtocols = sslProtocols;
+
+ InitSocket();
+ }
+
+ public TTlsSocketTransport(string host, int port, int timeout,
+ X509Certificate2 certificate,
+ RemoteCertificateValidationCallback certValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ SslProtocols sslProtocols = SslProtocols.Tls12)
+ {
+ try
+ {
+ var entry = Dns.GetHostEntry(host);
+ if (entry.AddressList.Length == 0)
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, "unable to resolve host name");
+
+ var addr = entry.AddressList[0];
+
+ _host = new IPAddress(addr.GetAddressBytes(), addr.ScopeId);
+ _port = port;
+ _timeout = timeout;
+ _certificate = certificate;
+ _certValidator = certValidator;
+ _localCertificateSelectionCallback = localCertificateSelectionCallback;
+ _sslProtocols = sslProtocols;
+
+ InitSocket();
+ }
+ catch (SocketException e)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown, e.Message, e);
+ }
+ }
+
+ public int Timeout
+ {
+ set { _client.ReceiveTimeout = _client.SendTimeout = _timeout = value; }
+ }
+
+ public TcpClient TcpClient => _client;
+
+ public IPAddress Host => _host;
+
+ public int Port => _port;
+
+ public override bool IsOpen
+ {
+ get
+ {
+ if (_client == null)
+ {
+ return false;
+ }
+
+ return _client.Connected;
+ }
+ }
+
+ private void InitSocket()
+ {
+ _client = new TcpClient();
+ _client.ReceiveTimeout = _client.SendTimeout = _timeout;
+ _client.Client.NoDelay = true;
+ }
+
+ private bool DefaultCertificateValidator(object sender, X509Certificate certificate, X509Chain chain,
+ SslPolicyErrors sslValidationErrors)
+ {
+ return sslValidationErrors == SslPolicyErrors.None;
+ }
+
+ public override async Task OpenAsync(CancellationToken cancellationToken)
+ {
+ if (IsOpen)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
+ }
+
+ if (_host == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
+ }
+
+ if (_port <= 0)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port");
+ }
+
+ if (_client == null)
+ {
+ InitSocket();
+ }
+
+ if (_client != null)
+ {
+ await _client.ConnectAsync(_host, _port);
+ await SetupTlsAsync();
+ }
+ }
+
+ public async Task SetupTlsAsync()
+ {
+ var validator = _certValidator ?? DefaultCertificateValidator;
+
+ if (_localCertificateSelectionCallback != null)
+ {
+ _secureStream = new SslStream(_client.GetStream(), false, validator, _localCertificateSelectionCallback);
+ }
+ else
+ {
+ _secureStream = new SslStream(_client.GetStream(), false, validator);
+ }
+
+ try
+ {
+ if (_isServer)
+ {
+ // Server authentication
+ await
+ _secureStream.AuthenticateAsServerAsync(_certificate, _certValidator != null, _sslProtocols,
+ true);
+ }
+ else
+ {
+ // Client authentication
+ var certs = _certificate != null
+ ? new X509CertificateCollection {_certificate}
+ : new X509CertificateCollection();
+
+ var targetHost = _host.ToString();
+ await _secureStream.AuthenticateAsClientAsync(targetHost, certs, _sslProtocols, true);
+ }
+ }
+ catch (Exception)
+ {
+ Close();
+ throw;
+ }
+
+ InputStream = _secureStream;
+ OutputStream = _secureStream;
+ }
+
+ public override void Close()
+ {
+ base.Close();
+ if (_client != null)
+ {
+ _client.Dispose();
+ _client = null;
+ }
+
+ if (_secureStream != null)
+ {
+ _secureStream.Dispose();
+ _secureStream = null;
+ }
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Transport/Server/NullLogger.cs b/lib/netstd/Thrift/Transport/Server/NullLogger.cs
new file mode 100644
index 0000000..1f1f542
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/Server/NullLogger.cs
@@ -0,0 +1,56 @@
+// 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.
+
+using Microsoft.Extensions.Logging;
+using System;
+
+
+namespace Thrift.Transport.Server
+{
+ // sometimes we just don't want to log anything
+ internal class NullLogger<T> : IDisposable, ILogger, ILogger<T>
+ {
+ internal class NullScope : IDisposable
+ {
+ public void Dispose()
+ {
+ // nothing to do
+ }
+ }
+
+ public IDisposable BeginScope<TState>(TState state)
+ {
+ return new NullScope();
+ }
+
+ public void Dispose()
+ {
+ // nothing to do
+ }
+
+ public bool IsEnabled(LogLevel logLevel)
+ {
+ return false; // no
+ }
+
+ public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
+ {
+ // do nothing
+ }
+ }
+}
+
diff --git a/lib/netstd/Thrift/Transport/Server/THttpServerTransport.cs b/lib/netstd/Thrift/Transport/Server/THttpServerTransport.cs
new file mode 100644
index 0000000..056300c
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/Server/THttpServerTransport.cs
@@ -0,0 +1,118 @@
+// 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.
+
+using System;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using Thrift.Processor;
+using Thrift.Protocol;
+using Thrift.Transport.Client;
+
+namespace Thrift.Transport.Server
+{
+ // ReSharper disable once InconsistentNaming
+ public class THttpServerTransport
+ {
+ protected const string ContentType = "application/x-thrift";
+ private readonly ILogger _logger;
+ private readonly RequestDelegate _next;
+ protected Encoding Encoding = Encoding.UTF8;
+
+ protected TProtocolFactory InputProtocolFactory;
+ protected TProtocolFactory OutputProtocolFactory;
+
+ protected TTransportFactory InputTransportFactory;
+ protected TTransportFactory OutputTransportFactory;
+
+ protected ITAsyncProcessor Processor;
+
+ public THttpServerTransport(ITAsyncProcessor processor, RequestDelegate next = null, ILoggerFactory loggerFactory = null)
+ : this(processor, new TBinaryProtocol.Factory(), null, next, loggerFactory)
+ {
+ }
+
+ public THttpServerTransport(
+ ITAsyncProcessor processor,
+ TProtocolFactory protocolFactory,
+ TTransportFactory transFactory = null,
+ RequestDelegate next = null,
+ ILoggerFactory loggerFactory = null)
+ : this(processor, protocolFactory, protocolFactory, transFactory, transFactory, next, loggerFactory)
+ {
+ }
+
+ public THttpServerTransport(
+ ITAsyncProcessor processor,
+ TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory,
+ TTransportFactory inputTransFactory = null,
+ TTransportFactory outputTransFactory = null,
+ RequestDelegate next = null,
+ ILoggerFactory loggerFactory = null)
+ {
+ // loggerFactory == null is not illegal anymore
+
+ Processor = processor ?? throw new ArgumentNullException(nameof(processor));
+ InputProtocolFactory = inputProtocolFactory ?? throw new ArgumentNullException(nameof(inputProtocolFactory));
+ OutputProtocolFactory = outputProtocolFactory ?? throw new ArgumentNullException(nameof(outputProtocolFactory));
+
+ InputTransportFactory = inputTransFactory;
+ OutputTransportFactory = outputTransFactory;
+
+ _next = next;
+ _logger = (loggerFactory != null) ? loggerFactory.CreateLogger<THttpServerTransport>() : new NullLogger<THttpServerTransport>();
+ }
+
+ public async Task Invoke(HttpContext context)
+ {
+ context.Response.ContentType = ContentType;
+ await ProcessRequestAsync(context, context.RequestAborted); //TODO: check for correct logic
+ }
+
+ public async Task ProcessRequestAsync(HttpContext context, CancellationToken cancellationToken)
+ {
+ var transport = new TStreamTransport(context.Request.Body, context.Response.Body);
+
+ try
+ {
+ var intrans = (InputTransportFactory != null) ? InputTransportFactory.GetTransport(transport) : transport;
+ var outtrans = (OutputTransportFactory != null) ? OutputTransportFactory.GetTransport(transport) : transport;
+
+ var input = InputProtocolFactory.GetProtocol(intrans);
+ var output = OutputProtocolFactory.GetProtocol(outtrans);
+
+ while (await Processor.ProcessAsync(input, output, cancellationToken))
+ {
+ if (!context.Response.HasStarted) // oneway method called
+ await context.Response.Body.FlushAsync(cancellationToken);
+ }
+ }
+ catch (TTransportException)
+ {
+ if (!context.Response.HasStarted) // if something goes bust, let the client know
+ context.Response.StatusCode = 500;
+ }
+ finally
+ {
+ transport.Close();
+ }
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs
new file mode 100644
index 0000000..8147d67
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs
@@ -0,0 +1,300 @@
+// 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.
+
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.IO.Pipes;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+using System.ComponentModel;
+using System.Security.AccessControl;
+using System.Security.Principal;
+
+namespace Thrift.Transport.Server
+{
+ // ReSharper disable once InconsistentNaming
+ public class TNamedPipeServerTransport : TServerTransport
+ {
+ /// <summary>
+ /// This is the address of the Pipe on the localhost.
+ /// </summary>
+ private readonly string _pipeAddress;
+ private bool _asyncMode = true;
+ private volatile bool _isPending = true;
+ private NamedPipeServerStream _stream = null;
+
+ public TNamedPipeServerTransport(string pipeAddress)
+ {
+ _pipeAddress = pipeAddress;
+ }
+
+ public override void Listen()
+ {
+ // nothing to do here
+ }
+
+ public override void Close()
+ {
+ if (_stream != null)
+ {
+ try
+ {
+ if (_stream.IsConnected)
+ _stream.Disconnect();
+ _stream.Dispose();
+ }
+ finally
+ {
+ _stream = null;
+ _isPending = false;
+ }
+ }
+ }
+
+ public override bool IsClientPending()
+ {
+ return _isPending;
+ }
+
+ private void EnsurePipeInstance()
+ {
+ if (_stream == null)
+ {
+ const PipeDirection direction = PipeDirection.InOut;
+ const int maxconn = NamedPipeServerStream.MaxAllowedServerInstances;
+ const PipeTransmissionMode mode = PipeTransmissionMode.Byte;
+ const int inbuf = 4096;
+ const int outbuf = 4096;
+ var options = _asyncMode ? PipeOptions.Asynchronous : PipeOptions.None;
+
+
+ // TODO: "CreatePipeNative" ist only a workaround, and there are have basically two possible outcomes:
+ // - once NamedPipeServerStream() gets a CTOR that supports pipesec, remove CreatePipeNative()
+ // - if 31190 gets resolved before, use _stream.SetAccessControl(pipesec) instead of CreatePipeNative()
+ // EITHER WAY,
+ // - if CreatePipeNative() finally gets removed, also remove "allow unsafe code" from the project settings
+
+ try
+ {
+ var handle = CreatePipeNative(_pipeAddress, inbuf, outbuf);
+ if( (handle != null) && (!handle.IsInvalid))
+ _stream = new NamedPipeServerStream(PipeDirection.InOut, _asyncMode, false, handle);
+ else
+ _stream = new NamedPipeServerStream(_pipeAddress, direction, maxconn, mode, options, inbuf, outbuf/*, pipesec*/);
+ }
+ catch (NotImplementedException) // Mono still does not support async, fallback to sync
+ {
+ if (_asyncMode)
+ {
+ options &= (~PipeOptions.Asynchronous);
+ _stream = new NamedPipeServerStream(_pipeAddress, direction, maxconn, mode, options, inbuf, outbuf);
+ _asyncMode = false;
+ }
+ else
+ {
+ throw;
+ }
+ }
+ }
+ }
+
+
+ #region CreatePipeNative workaround
+
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal class SECURITY_ATTRIBUTES
+ {
+ internal int nLength = 0;
+ internal IntPtr lpSecurityDescriptor = IntPtr.Zero;
+ internal int bInheritHandle = 0;
+ }
+
+
+ private const string Kernel32 = "kernel32.dll";
+
+ [DllImport(Kernel32, SetLastError = true)]
+ internal static extern IntPtr CreateNamedPipe(
+ string lpName, uint dwOpenMode, uint dwPipeMode,
+ uint nMaxInstances, uint nOutBufferSize, uint nInBufferSize, uint nDefaultTimeOut,
+ SECURITY_ATTRIBUTES pipeSecurityDescriptor
+ );
+
+
+
+ // Workaround: create the pipe via API call
+ // we have to do it this way, since NamedPipeServerStream() for netstd still lacks a few CTORs
+ // and _stream.SetAccessControl(pipesec); only keeps throwing ACCESS_DENIED errors at us
+ // References:
+ // - https://github.com/dotnet/corefx/issues/30170 (closed, continued in 31190)
+ // - https://github.com/dotnet/corefx/issues/31190 System.IO.Pipes.AccessControl package does not work
+ // - https://github.com/dotnet/corefx/issues/24040 NamedPipeServerStream: Provide support for WRITE_DAC
+ // - https://github.com/dotnet/corefx/issues/34400 Have a mechanism for lower privileged user to connect to a privileged user's pipe
+ private SafePipeHandle CreatePipeNative(string name, int inbuf, int outbuf)
+ {
+ if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+ return null; // Windows only
+
+ var pinningHandle = new GCHandle();
+ try
+ {
+ // owner gets full access, everyone else read/write
+ var pipesec = new PipeSecurity();
+ using (var currentIdentity = WindowsIdentity.GetCurrent())
+ {
+ var sidOwner = currentIdentity.Owner;
+ var sidWorld = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
+
+ pipesec.SetOwner(sidOwner);
+ pipesec.AddAccessRule(new PipeAccessRule(sidOwner, PipeAccessRights.FullControl, AccessControlType.Allow));
+ pipesec.AddAccessRule(new PipeAccessRule(sidWorld, PipeAccessRights.ReadWrite, AccessControlType.Allow));
+ }
+
+ // create a security descriptor and assign it to the security attribs
+ var secAttrs = new SECURITY_ATTRIBUTES();
+ byte[] sdBytes = pipesec.GetSecurityDescriptorBinaryForm();
+ pinningHandle = GCHandle.Alloc(sdBytes, GCHandleType.Pinned);
+ unsafe {
+ fixed (byte* pSD = sdBytes) {
+ secAttrs.lpSecurityDescriptor = (IntPtr)pSD;
+ }
+ }
+
+ // a bunch of constants we will need shortly
+ const int PIPE_ACCESS_DUPLEX = 0x00000003;
+ const int FILE_FLAG_OVERLAPPED = 0x40000000;
+ const int WRITE_DAC = 0x00040000;
+ const int PIPE_TYPE_BYTE = 0x00000000;
+ const int PIPE_READMODE_BYTE = 0x00000000;
+ const int PIPE_UNLIMITED_INSTANCES = 255;
+
+ // create the pipe via API call
+ var rawHandle = CreateNamedPipe(
+ @"\\.\pipe\" + name,
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
+ PIPE_UNLIMITED_INSTANCES, (uint)inbuf, (uint)outbuf,
+ 5 * 1000,
+ secAttrs
+ );
+
+ // make a SafePipeHandle() from it
+ var handle = new SafePipeHandle(rawHandle, true);
+ if (handle.IsInvalid)
+ throw new Win32Exception(Marshal.GetLastWin32Error());
+
+ // return it (to be packaged)
+ return handle;
+ }
+ finally
+ {
+ if (pinningHandle.IsAllocated)
+ pinningHandle.Free();
+ }
+ }
+
+ #endregion
+
+ protected override async Task<TTransport> AcceptImplementationAsync(CancellationToken cancellationToken)
+ {
+ try
+ {
+ EnsurePipeInstance();
+
+ await _stream.WaitForConnectionAsync(cancellationToken);
+
+ var trans = new ServerTransport(_stream);
+ _stream = null; // pass ownership to ServerTransport
+
+ //_isPending = false;
+
+ return trans;
+ }
+ catch (TTransportException)
+ {
+ Close();
+ throw;
+ }
+ catch (Exception e)
+ {
+ Close();
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, e.Message);
+ }
+ }
+
+ private class ServerTransport : TTransport
+ {
+ private readonly NamedPipeServerStream _stream;
+
+ public ServerTransport(NamedPipeServerStream stream)
+ {
+ _stream = stream;
+ }
+
+ public override bool IsOpen => _stream != null && _stream.IsConnected;
+
+ public override async Task OpenAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ public override void Close()
+ {
+ _stream?.Dispose();
+ }
+
+ public override async Task<int> ReadAsync(byte[] buffer, int offset, int length,
+ CancellationToken cancellationToken)
+ {
+ if (_stream == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ return await _stream.ReadAsync(buffer, offset, length, cancellationToken);
+ }
+
+ public override async Task WriteAsync(byte[] buffer, int offset, int length,
+ CancellationToken cancellationToken)
+ {
+ if (_stream == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ await _stream.WriteAsync(buffer, offset, length, cancellationToken);
+ }
+
+ public override async Task FlushAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.FromCanceled(cancellationToken);
+ }
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ _stream?.Dispose();
+ }
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs b/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs
new file mode 100644
index 0000000..0f90841
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs
@@ -0,0 +1,139 @@
+// 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.
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Transport.Client;
+
+namespace Thrift.Transport.Server
+{
+
+ // ReSharper disable once InconsistentNaming
+ public class TServerSocketTransport : TServerTransport
+ {
+ private readonly int _clientTimeout;
+ private TcpListener _server;
+
+ public TServerSocketTransport(TcpListener listener, int clientTimeout = 0)
+ {
+ _server = listener;
+ _clientTimeout = clientTimeout;
+ }
+
+ public TServerSocketTransport(int port, int clientTimeout = 0)
+ : this(null, clientTimeout)
+ {
+ try
+ {
+ // Make server socket
+ _server = new TcpListener(IPAddress.Any, port);
+ _server.Server.NoDelay = true;
+ }
+ catch (Exception)
+ {
+ _server = null;
+ throw new TTransportException("Could not create ServerSocket on port " + port + ".");
+ }
+ }
+
+ public override void Listen()
+ {
+ // Make sure not to block on accept
+ if (_server != null)
+ {
+ try
+ {
+ _server.Start();
+ }
+ catch (SocketException sx)
+ {
+ throw new TTransportException("Could not accept on listening socket: " + sx.Message);
+ }
+ }
+ }
+
+ public override bool IsClientPending()
+ {
+ return _server.Pending();
+ }
+
+ protected override async Task<TTransport> AcceptImplementationAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<TTransport>(cancellationToken);
+ }
+
+ if (_server == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
+ }
+
+ try
+ {
+ TTransport tSocketTransport = null;
+ var tcpClient = await _server.AcceptTcpClientAsync();
+
+ try
+ {
+ tSocketTransport = new TSocketTransport(tcpClient)
+ {
+ Timeout = _clientTimeout
+ };
+
+ return tSocketTransport;
+ }
+ catch (Exception)
+ {
+ if (tSocketTransport != null)
+ {
+ tSocketTransport.Dispose();
+ }
+ else // Otherwise, clean it up ourselves.
+ {
+ ((IDisposable) tcpClient).Dispose();
+ }
+
+ throw;
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new TTransportException(ex.ToString());
+ }
+ }
+
+ public override void Close()
+ {
+ if (_server != null)
+ {
+ try
+ {
+ _server.Stop();
+ }
+ catch (Exception ex)
+ {
+ throw new TTransportException("WARNING: Could not close server socket: " + ex);
+ }
+ _server = null;
+ }
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Transport/Server/TTlsServerSocketTransport.cs b/lib/netstd/Thrift/Transport/Server/TTlsServerSocketTransport.cs
new file mode 100644
index 0000000..5070919
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/Server/TTlsServerSocketTransport.cs
@@ -0,0 +1,150 @@
+// 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.
+
+using System;
+using System.Net;
+using System.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Transport.Client;
+
+namespace Thrift.Transport.Server
+{
+ // ReSharper disable once InconsistentNaming
+ public class TTlsServerSocketTransport : TServerTransport
+ {
+ private readonly RemoteCertificateValidationCallback _clientCertValidator;
+ private readonly int _clientTimeout = 0;
+ private readonly LocalCertificateSelectionCallback _localCertificateSelectionCallback;
+ private readonly X509Certificate2 _serverCertificate;
+ private readonly SslProtocols _sslProtocols;
+ private TcpListener _server;
+
+ public TTlsServerSocketTransport(
+ TcpListener listener,
+ X509Certificate2 certificate,
+ RemoteCertificateValidationCallback clientCertValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ SslProtocols sslProtocols = SslProtocols.Tls12)
+ {
+ if (!certificate.HasPrivateKey)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.Unknown,
+ "Your server-certificate needs to have a private key");
+ }
+
+ _serverCertificate = certificate;
+ _clientCertValidator = clientCertValidator;
+ _localCertificateSelectionCallback = localCertificateSelectionCallback;
+ _sslProtocols = sslProtocols;
+ _server = listener;
+ }
+
+ public TTlsServerSocketTransport(
+ int port,
+ X509Certificate2 certificate,
+ RemoteCertificateValidationCallback clientCertValidator = null,
+ LocalCertificateSelectionCallback localCertificateSelectionCallback = null,
+ SslProtocols sslProtocols = SslProtocols.Tls12)
+ : this(null, certificate, clientCertValidator, localCertificateSelectionCallback)
+ {
+ try
+ {
+ // Create server socket
+ _server = new TcpListener(IPAddress.Any, port);
+ _server.Server.NoDelay = true;
+ }
+ catch (Exception)
+ {
+ _server = null;
+ throw new TTransportException($"Could not create ServerSocket on port {port}.");
+ }
+ }
+
+ public override void Listen()
+ {
+ // Make sure accept is not blocking
+ if (_server != null)
+ {
+ try
+ {
+ _server.Start();
+ }
+ catch (SocketException sx)
+ {
+ throw new TTransportException($"Could not accept on listening socket: {sx.Message}");
+ }
+ }
+ }
+
+ public override bool IsClientPending()
+ {
+ return _server.Pending();
+ }
+
+ protected override async Task<TTransport> AcceptImplementationAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<TTransport>(cancellationToken);
+ }
+
+ if (_server == null)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
+ }
+
+ try
+ {
+ var client = await _server.AcceptTcpClientAsync();
+ client.SendTimeout = client.ReceiveTimeout = _clientTimeout;
+
+ //wrap the client in an SSL Socket passing in the SSL cert
+ var tTlsSocket = new TTlsSocketTransport(client, _serverCertificate, true, _clientCertValidator,
+ _localCertificateSelectionCallback, _sslProtocols);
+
+ await tTlsSocket.SetupTlsAsync();
+
+ return tTlsSocket;
+ }
+ catch (Exception ex)
+ {
+ throw new TTransportException(ex.ToString());
+ }
+ }
+
+ public override void Close()
+ {
+ if (_server != null)
+ {
+ try
+ {
+ _server.Stop();
+ }
+ catch (Exception ex)
+ {
+ throw new TTransportException($"WARNING: Could not close server socket: {ex}");
+ }
+
+ _server = null;
+ }
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Transport/TBufferedTransport.cs b/lib/netstd/Thrift/Transport/TBufferedTransport.cs
new file mode 100644
index 0000000..c648f5c
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/TBufferedTransport.cs
@@ -0,0 +1,213 @@
+// 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.
+
+using System;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Thrift.Transport
+{
+ // ReSharper disable once InconsistentNaming
+ public class TBufferedTransport : TTransport
+ {
+ private readonly int _bufSize;
+ private readonly MemoryStream _inputBuffer = new MemoryStream(0);
+ private readonly MemoryStream _outputBuffer = new MemoryStream(0);
+ private readonly TTransport _transport;
+ private bool _isDisposed;
+
+ public class Factory : TTransportFactory
+ {
+ public override TTransport GetTransport(TTransport trans)
+ {
+ return new TBufferedTransport(trans);
+ }
+ }
+
+ //TODO: should support only specified input transport?
+ public TBufferedTransport(TTransport transport, int bufSize = 1024)
+ {
+ if (bufSize <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(bufSize), "Buffer size must be a positive number.");
+ }
+
+ _transport = transport ?? throw new ArgumentNullException(nameof(transport));
+ _bufSize = bufSize;
+ }
+
+ public TTransport UnderlyingTransport
+ {
+ get
+ {
+ CheckNotDisposed();
+
+ return _transport;
+ }
+ }
+
+ public override bool IsOpen => !_isDisposed && _transport.IsOpen;
+
+ public override async Task OpenAsync(CancellationToken cancellationToken)
+ {
+ CheckNotDisposed();
+
+ await _transport.OpenAsync(cancellationToken);
+ }
+
+ public override void Close()
+ {
+ CheckNotDisposed();
+
+ _transport.Close();
+ }
+
+ public override async Task<int> ReadAsync(byte[] buffer, int offset, int length,
+ CancellationToken cancellationToken)
+ {
+ //TODO: investigate how it should work correctly
+ CheckNotDisposed();
+
+ ValidateBufferArgs(buffer, offset, length);
+
+ if (!IsOpen)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ if (_inputBuffer.Capacity < _bufSize)
+ {
+ _inputBuffer.Capacity = _bufSize;
+ }
+
+ var got = await _inputBuffer.ReadAsync(buffer, offset, length, cancellationToken);
+ if (got > 0)
+ {
+ return got;
+ }
+
+ _inputBuffer.Seek(0, SeekOrigin.Begin);
+ _inputBuffer.SetLength(_inputBuffer.Capacity);
+
+ ArraySegment<byte> bufSegment;
+ _inputBuffer.TryGetBuffer(out bufSegment);
+
+ // investigate
+ var filled = await _transport.ReadAsync(bufSegment.Array, 0, (int) _inputBuffer.Length, cancellationToken);
+ _inputBuffer.SetLength(filled);
+
+ if (filled == 0)
+ {
+ return 0;
+ }
+
+ return await ReadAsync(buffer, offset, length, cancellationToken);
+ }
+
+ public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
+ {
+ CheckNotDisposed();
+
+ ValidateBufferArgs(buffer, offset, length);
+
+ if (!IsOpen)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ // Relative offset from "off" argument
+ var writtenCount = 0;
+ if (_outputBuffer.Length > 0)
+ {
+ var capa = (int) (_outputBuffer.Capacity - _outputBuffer.Length);
+ var writeSize = capa <= length ? capa : length;
+ await _outputBuffer.WriteAsync(buffer, offset, writeSize, cancellationToken);
+
+ writtenCount += writeSize;
+ if (writeSize == capa)
+ {
+ //ArraySegment<byte> bufSegment;
+ //_outputBuffer.TryGetBuffer(out bufSegment);
+ var data = _outputBuffer.ToArray();
+ //await _transport.WriteAsync(bufSegment.Array, cancellationToken);
+ await _transport.WriteAsync(data, cancellationToken);
+ _outputBuffer.SetLength(0);
+ }
+ }
+
+ while (length - writtenCount >= _bufSize)
+ {
+ await _transport.WriteAsync(buffer, offset + writtenCount, _bufSize, cancellationToken);
+ writtenCount += _bufSize;
+ }
+
+ var remain = length - writtenCount;
+ if (remain > 0)
+ {
+ if (_outputBuffer.Capacity < _bufSize)
+ {
+ _outputBuffer.Capacity = _bufSize;
+ }
+ await _outputBuffer.WriteAsync(buffer, offset + writtenCount, remain, cancellationToken);
+ }
+ }
+
+ public override async Task FlushAsync(CancellationToken cancellationToken)
+ {
+ CheckNotDisposed();
+
+ if (!IsOpen)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ if (_outputBuffer.Length > 0)
+ {
+ var data = _outputBuffer.ToArray();
+
+ await _transport.WriteAsync(data /*bufSegment.Array*/, cancellationToken);
+ _outputBuffer.SetLength(0);
+ }
+
+ await _transport.FlushAsync(cancellationToken);
+ }
+
+ private void CheckNotDisposed()
+ {
+ if (_isDisposed)
+ {
+ throw new ObjectDisposedException(nameof(_transport));
+ }
+ }
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_isDisposed)
+ {
+ if (disposing)
+ {
+ _inputBuffer?.Dispose();
+ _outputBuffer?.Dispose();
+ _transport?.Dispose();
+ }
+ }
+ _isDisposed = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Transport/TFramedTransport.cs b/lib/netstd/Thrift/Transport/TFramedTransport.cs
new file mode 100644
index 0000000..fe7793e
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/TFramedTransport.cs
@@ -0,0 +1,207 @@
+// 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.
+
+using System;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Thrift.Transport
+{
+ // ReSharper disable once InconsistentNaming
+ public class TFramedTransport : TTransport
+ {
+ private const int HeaderSize = 4;
+ private readonly byte[] _headerBuf = new byte[HeaderSize];
+ private readonly MemoryStream _readBuffer = new MemoryStream(1024);
+ private readonly TTransport _transport;
+ private readonly MemoryStream _writeBuffer = new MemoryStream(1024);
+
+ private bool _isDisposed;
+
+ public class Factory : TTransportFactory
+ {
+ public override TTransport GetTransport(TTransport trans)
+ {
+ return new TFramedTransport(trans);
+ }
+ }
+
+ public TFramedTransport(TTransport transport)
+ {
+ _transport = transport ?? throw new ArgumentNullException(nameof(transport));
+
+ InitWriteBuffer();
+ }
+
+ public override bool IsOpen => !_isDisposed && _transport.IsOpen;
+
+ public override async Task OpenAsync(CancellationToken cancellationToken)
+ {
+ CheckNotDisposed();
+
+ await _transport.OpenAsync(cancellationToken);
+ }
+
+ public override void Close()
+ {
+ CheckNotDisposed();
+
+ _transport.Close();
+ }
+
+ public override async Task<int> ReadAsync(byte[] buffer, int offset, int length,
+ CancellationToken cancellationToken)
+ {
+ CheckNotDisposed();
+
+ ValidateBufferArgs(buffer, offset, length);
+
+ if (!IsOpen)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ var got = await _readBuffer.ReadAsync(buffer, offset, length, cancellationToken);
+ if (got > 0)
+ {
+ return got;
+ }
+
+ // Read another frame of data
+ await ReadFrameAsync(cancellationToken);
+
+ return await _readBuffer.ReadAsync(buffer, offset, length, cancellationToken);
+ }
+
+ private async Task ReadFrameAsync(CancellationToken cancellationToken)
+ {
+ await _transport.ReadAllAsync(_headerBuf, 0, HeaderSize, cancellationToken);
+
+ var size = DecodeFrameSize(_headerBuf);
+
+ _readBuffer.SetLength(size);
+ _readBuffer.Seek(0, SeekOrigin.Begin);
+
+ ArraySegment<byte> bufSegment;
+ _readBuffer.TryGetBuffer(out bufSegment);
+
+ var buff = bufSegment.Array;
+
+ await _transport.ReadAllAsync(buff, 0, size, cancellationToken);
+ }
+
+ public override async Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken)
+ {
+ CheckNotDisposed();
+
+ ValidateBufferArgs(buffer, offset, length);
+
+ if (!IsOpen)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ if (_writeBuffer.Length + length > int.MaxValue)
+ {
+ await FlushAsync(cancellationToken);
+ }
+
+ await _writeBuffer.WriteAsync(buffer, offset, length, cancellationToken);
+ }
+
+ public override async Task FlushAsync(CancellationToken cancellationToken)
+ {
+ CheckNotDisposed();
+
+ if (!IsOpen)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.NotOpen);
+ }
+
+ //ArraySegment<byte> bufSegment;
+ //_writeBuffer.TryGetBuffer(out bufSegment);
+ //var buf = bufSegment.Array;
+ var buf = _writeBuffer.ToArray();
+
+ //var len = (int)_writeBuffer.Length;
+ var dataLen = (int) _writeBuffer.Length - HeaderSize;
+ if (dataLen < 0)
+ {
+ throw new InvalidOperationException(); // logic error actually
+ }
+
+ // Inject message header into the reserved buffer space
+ EncodeFrameSize(dataLen, buf);
+
+ // Send the entire message at once
+ await _transport.WriteAsync(buf, cancellationToken);
+
+ InitWriteBuffer();
+
+ await _transport.FlushAsync(cancellationToken);
+ }
+
+ private void InitWriteBuffer()
+ {
+ // Reserve space for message header to be put right before sending it out
+ _writeBuffer.SetLength(HeaderSize);
+ _writeBuffer.Seek(0, SeekOrigin.End);
+ }
+
+ private static void EncodeFrameSize(int frameSize, byte[] buf)
+ {
+ buf[0] = (byte) (0xff & (frameSize >> 24));
+ buf[1] = (byte) (0xff & (frameSize >> 16));
+ buf[2] = (byte) (0xff & (frameSize >> 8));
+ buf[3] = (byte) (0xff & (frameSize));
+ }
+
+ private static int DecodeFrameSize(byte[] buf)
+ {
+ return
+ ((buf[0] & 0xff) << 24) |
+ ((buf[1] & 0xff) << 16) |
+ ((buf[2] & 0xff) << 8) |
+ (buf[3] & 0xff);
+ }
+
+
+ private void CheckNotDisposed()
+ {
+ if (_isDisposed)
+ {
+ throw new ObjectDisposedException("TFramedTransport");
+ }
+ }
+
+ // IDisposable
+ protected override void Dispose(bool disposing)
+ {
+ if (!_isDisposed)
+ {
+ if (disposing)
+ {
+ _readBuffer?.Dispose();
+ _writeBuffer?.Dispose();
+ _transport?.Dispose();
+ }
+ }
+ _isDisposed = true;
+ }
+ }
+}
diff --git a/lib/netstd/Thrift/Transport/TServerTransport.cs b/lib/netstd/Thrift/Transport/TServerTransport.cs
new file mode 100644
index 0000000..e25c0c5
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/TServerTransport.cs
@@ -0,0 +1,54 @@
+// 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.
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Thrift.Transport
+{
+ // ReSharper disable once InconsistentNaming
+ public abstract class TServerTransport
+ {
+ public abstract void Listen();
+ public abstract void Close();
+ public abstract bool IsClientPending();
+
+ protected virtual async Task<TTransport> AcceptImplementationAsync()
+ {
+ return await AcceptImplementationAsync(CancellationToken.None);
+ }
+
+ protected abstract Task<TTransport> AcceptImplementationAsync(CancellationToken cancellationToken);
+
+ public async Task<TTransport> AcceptAsync()
+ {
+ return await AcceptAsync(CancellationToken.None);
+ }
+
+ public async Task<TTransport> AcceptAsync(CancellationToken cancellationToken)
+ {
+ var transport = await AcceptImplementationAsync(cancellationToken);
+
+ if (transport == null)
+ {
+ throw new TTransportException($"{nameof(AcceptImplementationAsync)} should not return null");
+ }
+
+ return transport;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Transport/TTransport.cs b/lib/netstd/Thrift/Transport/TTransport.cs
new file mode 100644
index 0000000..d5c8186
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/TTransport.cs
@@ -0,0 +1,179 @@
+// 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.
+
+using System;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Thrift.Transport
+{
+ //TODO: think about client info
+ // ReSharper disable once InconsistentNaming
+ public abstract class TTransport : IDisposable
+ {
+ //TODO: think how to avoid peek byte
+ private readonly byte[] _peekBuffer = new byte[1];
+ private bool _hasPeekByte;
+ public abstract bool IsOpen { get; }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ public async Task<bool> PeekAsync(CancellationToken cancellationToken)
+ {
+ //If we already have a byte read but not consumed, do nothing.
+ if (_hasPeekByte)
+ {
+ return true;
+ }
+
+ //If transport closed we can't peek.
+ if (!IsOpen)
+ {
+ return false;
+ }
+
+ //Try to read one byte. If succeeds we will need to store it for the next read.
+ try
+ {
+ var bytes = await ReadAsync(_peekBuffer, 0, 1, cancellationToken);
+ if (bytes == 0)
+ {
+ return false;
+ }
+ }
+ catch (IOException)
+ {
+ return false;
+ }
+
+ _hasPeekByte = true;
+ return true;
+ }
+
+ public virtual async Task OpenAsync()
+ {
+ await OpenAsync(CancellationToken.None);
+ }
+
+ public abstract Task OpenAsync(CancellationToken cancellationToken);
+
+ public abstract void Close();
+
+ protected static void ValidateBufferArgs(byte[] buffer, int offset, int length)
+ {
+ if (buffer == null)
+ {
+ throw new ArgumentNullException(nameof(buffer));
+ }
+
+ if (offset < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(offset), "Buffer offset is smaller than zero.");
+ }
+
+ if (length < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), "Buffer length is smaller than zero.");
+ }
+
+ if (offset + length > buffer.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(buffer), "Not enough data.");
+ }
+ }
+
+ public virtual async Task<int> ReadAsync(byte[] buffer, int offset, int length)
+ {
+ return await ReadAsync(buffer, offset, length, CancellationToken.None);
+ }
+
+ public abstract Task<int> ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken);
+
+ public virtual async Task<int> ReadAllAsync(byte[] buffer, int offset, int length)
+ {
+ return await ReadAllAsync(buffer, offset, length, CancellationToken.None);
+ }
+
+ public virtual async Task<int> ReadAllAsync(byte[] buffer, int offset, int length,
+ CancellationToken cancellationToken)
+ {
+ ValidateBufferArgs(buffer, offset, length);
+
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<int>(cancellationToken);
+ }
+
+ var retrieved = 0;
+
+ //If we previously peeked a byte, we need to use that first.
+ if (_hasPeekByte)
+ {
+ buffer[offset + retrieved++] = _peekBuffer[0];
+ _hasPeekByte = false;
+ }
+
+ while (retrieved < length)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return await Task.FromCanceled<int>(cancellationToken);
+ }
+
+ var returnedCount = await ReadAsync(buffer, offset + retrieved, length - retrieved, cancellationToken);
+ if (returnedCount <= 0)
+ {
+ throw new TTransportException(TTransportException.ExceptionType.EndOfFile,
+ "Cannot read, Remote side has closed");
+ }
+ retrieved += returnedCount;
+ }
+ return retrieved;
+ }
+
+ public virtual async Task WriteAsync(byte[] buffer)
+ {
+ await WriteAsync(buffer, CancellationToken.None);
+ }
+
+ public virtual async Task WriteAsync(byte[] buffer, CancellationToken cancellationToken)
+ {
+ await WriteAsync(buffer, 0, buffer.Length, CancellationToken.None);
+ }
+
+ public virtual async Task WriteAsync(byte[] buffer, int offset, int length)
+ {
+ await WriteAsync(buffer, offset, length, CancellationToken.None);
+ }
+
+ public abstract Task WriteAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken);
+
+ public virtual async Task FlushAsync()
+ {
+ await FlushAsync(CancellationToken.None);
+ }
+
+ public abstract Task FlushAsync(CancellationToken cancellationToken);
+
+ protected abstract void Dispose(bool disposing);
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Transport/TTransportException.cs b/lib/netstd/Thrift/Transport/TTransportException.cs
new file mode 100644
index 0000000..760a178
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/TTransportException.cs
@@ -0,0 +1,60 @@
+// 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.
+
+using System;
+
+namespace Thrift.Transport
+{
+ // ReSharper disable once InconsistentNaming
+ public class TTransportException : TException
+ {
+ public enum ExceptionType
+ {
+ Unknown,
+ NotOpen,
+ AlreadyOpen,
+ TimedOut,
+ EndOfFile,
+ Interrupted
+ }
+
+ public ExceptionType ExType { get; private set; }
+
+ public TTransportException()
+ {
+ }
+
+ public TTransportException(ExceptionType exType, Exception inner = null)
+ : base(string.Empty, inner)
+ {
+ ExType = exType;
+ }
+
+ public TTransportException(ExceptionType exType, string message, Exception inner = null)
+ : base(message, inner)
+ {
+ ExType = exType;
+ }
+
+ public TTransportException(string message, Exception inner = null)
+ : base(message, inner)
+ {
+ }
+
+ public ExceptionType Type => ExType;
+ }
+}
\ No newline at end of file
diff --git a/lib/netstd/Thrift/Transport/TTransportFactory.cs b/lib/netstd/Thrift/Transport/TTransportFactory.cs
new file mode 100644
index 0000000..16e27ac
--- /dev/null
+++ b/lib/netstd/Thrift/Transport/TTransportFactory.cs
@@ -0,0 +1,35 @@
+// 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.
+
+namespace Thrift.Transport
+{
+ /// <summary>
+ /// From Mark Slee & Aditya Agarwal of Facebook:
+ /// Factory class used to create wrapped instance of Transports.
+ /// This is used primarily in servers, which get Transports from
+ /// a ServerTransport and then may want to mutate them (i.e. create
+ /// a BufferedTransport from the underlying base transport)
+ /// </summary>
+ // ReSharper disable once InconsistentNaming
+ public class TTransportFactory
+ {
+ public virtual TTransport GetTransport(TTransport trans)
+ {
+ return trans;
+ }
+ }
+}
diff --git a/lib/netstd/build.cmd b/lib/netstd/build.cmd
new file mode 100644
index 0000000..863c4b4
--- /dev/null
+++ b/lib/netstd/build.cmd
@@ -0,0 +1,27 @@
+@echo off
+rem /*
+rem * Licensed to the Apache Software Foundation (ASF) under one
+rem * or more contributor license agreements. See the NOTICE file
+rem * distributed with this work for additional information
+rem * regarding copyright ownership. The ASF licenses this file
+rem * to you under the Apache License, Version 2.0 (the
+rem * "License"); you may not use this file except in compliance
+rem * with the License. You may obtain a copy of the License at
+rem *
+rem * http://www.apache.org/licenses/LICENSE-2.0
+rem *
+rem * Unless required by applicable law or agreed to in writing,
+rem * software distributed under the License is distributed on an
+rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem * KIND, either express or implied. See the License for the
+rem * specific language governing permissions and limitations
+rem * under the License.
+rem */
+
+setlocal
+
+thrift -version
+dotnet --info
+dotnet build
+
+:eof
diff --git a/lib/cpp/thrift-qt.pc.in b/lib/netstd/build.sh
old mode 100755
new mode 100644
similarity index 74%
copy from lib/cpp/thrift-qt.pc.in
copy to lib/netstd/build.sh
index 5e60d84..ae18bce
--- a/lib/cpp/thrift-qt.pc.in
+++ b/lib/netstd/build.sh
@@ -1,3 +1,5 @@
+#!/usr/bin/env bash
+
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -17,14 +19,14 @@
# under the License.
#
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
+#exit if any command fails
+#set -e
-Name: Thrift
-Description: Thrift Qt API
-Version: @VERSION@
-Requires: thrift = @VERSION@
-Libs: -L${libdir} -lthriftqt
-Cflags: -I${includedir}
+thrift --version
+dotnet --info
+dotnet build
+
+#revision=${TRAVIS_JOB_ID:=1}
+#revision=$(printf "%04d" $revision)
+
+#dotnet pack ./src/PROJECT_NAME -c Release -o ./artifacts --version-suffix=$revision
diff --git a/lib/netstd/runtests.cmd b/lib/netstd/runtests.cmd
new file mode 100644
index 0000000..5114bc5
--- /dev/null
+++ b/lib/netstd/runtests.cmd
@@ -0,0 +1,28 @@
+@echo off
+rem /*
+rem * Licensed to the Apache Software Foundation (ASF) under one
+rem * or more contributor license agreements. See the NOTICE file
+rem * distributed with this work for additional information
+rem * regarding copyright ownership. The ASF licenses this file
+rem * to you under the Apache License, Version 2.0 (the
+rem * "License"); you may not use this file except in compliance
+rem * with the License. You may obtain a copy of the License at
+rem *
+rem * http://www.apache.org/licenses/LICENSE-2.0
+rem *
+rem * Unless required by applicable law or agreed to in writing,
+rem * software distributed under the License is distributed on an
+rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem * KIND, either express or implied. See the License for the
+rem * specific language governing permissions and limitations
+rem * under the License.
+rem */
+setlocal
+
+thrift -version
+dotnet --info
+
+dotnet test Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj
+dotnet test Tests\Thrift.Tests\Thrift.Tests.csproj
+
+:eof
diff --git a/lib/cpp/thrift-qt.pc.in b/lib/netstd/runtests.sh
old mode 100755
new mode 100644
similarity index 77%
rename from lib/cpp/thrift-qt.pc.in
rename to lib/netstd/runtests.sh
index 5e60d84..a26cc36
--- a/lib/cpp/thrift-qt.pc.in
+++ b/lib/netstd/runtests.sh
@@ -1,3 +1,5 @@
+#!/usr/bin/env bash
+
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -17,14 +19,8 @@
# under the License.
#
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
+thrift -version
+dotnet --info
-Name: Thrift
-Description: Thrift Qt API
-Version: @VERSION@
-Requires: thrift = @VERSION@
-Libs: -L${libdir} -lthriftqt
-Cflags: -I${includedir}
+dotnet test Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj
+dotnet test Tests\Thrift.Tests\Thrift.Tests.csproj
\ No newline at end of file
diff --git a/lib/nodejs/Makefile.am b/lib/nodejs/Makefile.am
index 68ea3ea..091f768 100755
--- a/lib/nodejs/Makefile.am
+++ b/lib/nodejs/Makefile.am
@@ -32,7 +32,7 @@
cd $(top_srcdir) && $(NPM) test && $(NPM) run lint-tests && cd lib/nodejs
clean-local:
- $(RM) -r test/gen-nodejs
+ $(RM) -r test/gen-*
$(RM) -r $(top_srcdir)/node_modules
EXTRA_DIST = \
diff --git a/lib/nodejs/examples/httpServer.py b/lib/nodejs/examples/httpServer.py
index b712fcd..76e9f4a 100644
--- a/lib/nodejs/examples/httpServer.py
+++ b/lib/nodejs/examples/httpServer.py
@@ -5,10 +5,12 @@
from thrift.protocol import TJSONProtocol
from thrift.server import THttpServer
+
class HelloSvcHandler:
- def hello_func(self):
- print("Hello Called")
- return "hello from Python"
+ def hello_func(self):
+ print("Hello Called")
+ return "hello from Python"
+
processor = HelloSvc.Processor(HelloSvcHandler())
protoFactory = TJSONProtocol.TJSONProtocolFactory()
diff --git a/lib/nodejs/lib/thrift/binary_protocol.js b/lib/nodejs/lib/thrift/binary_protocol.js
index 6ab9c05..af8836c 100644
--- a/lib/nodejs/lib/thrift/binary_protocol.js
+++ b/lib/nodejs/lib/thrift/binary_protocol.js
@@ -33,6 +33,10 @@
VERSION_1 = -2147418112, // 0x80010000
TYPE_MASK = 0x000000ff;
+TBinaryProtocol.VERSION_MASK = VERSION_MASK;
+TBinaryProtocol.VERSION_1 = VERSION_1;
+TBinaryProtocol.TYPE_MASK = TYPE_MASK
+
function TBinaryProtocol(trans, strictRead, strictWrite) {
this.trans = trans;
this.strictRead = (strictRead !== undefined ? strictRead : false);
diff --git a/lib/nodejs/lib/thrift/buffered_transport.js b/lib/nodejs/lib/thrift/buffered_transport.js
index a9e006e..113e216 100644
--- a/lib/nodejs/lib/thrift/buffered_transport.js
+++ b/lib/nodejs/lib/thrift/buffered_transport.js
@@ -19,6 +19,7 @@
var binary = require('./binary');
var InputBufferUnderrunError = require('./input_buffer_underrun_error');
+var THeaderTransport = require('./header_transport');
module.exports = TBufferedTransport;
@@ -33,6 +34,8 @@
this.onFlush = callback;
};
+TBufferedTransport.prototype = new THeaderTransport();
+
TBufferedTransport.prototype.reset = function() {
this.inBuf = new Buffer(this.defaultReadBufferSize);
this.readCursor = 0;
diff --git a/lib/nodejs/lib/thrift/connection.js b/lib/nodejs/lib/thrift/connection.js
index b545454..72ecb69 100644
--- a/lib/nodejs/lib/thrift/connection.js
+++ b/lib/nodejs/lib/thrift/connection.js
@@ -74,10 +74,7 @@
this.framePos = 0;
this.frame = null;
self.initialize_retry_vars();
-
- self.offline_queue.forEach(function(data) {
- self.connection.write(data);
- });
+ self.flush_offline_queue();
self.emit("connect");
});
@@ -177,6 +174,18 @@
this.attempts = 0;
};
+Connection.prototype.flush_offline_queue = function () {
+ var self = this;
+ var offline_queue = this.offline_queue;
+
+ // Reset offline queue
+ this.offline_queue = [];
+ // Attempt to write queued items
+ offline_queue.forEach(function(data) {
+ self.write(data);
+ });
+};
+
Connection.prototype.write = function(data) {
if (!this.connected) {
this.offline_queue.push(data);
@@ -221,6 +230,11 @@
});
this.retry_timer = setTimeout(function () {
+ if (self.connection.destroyed) {
+ self.retry_timer = null;
+ return;
+ }
+
log.debug("Retrying connection...");
self.retry_totaltime += self.retry_delay;
@@ -306,10 +320,7 @@
this.frame = null;
this.connected = true;
- self.offline_queue.forEach(function(data) {
- self.connection.write(data);
- });
-
+ self.flush_offline_queue();
this.connection.addListener("error", function(err) {
self.emit("error", err);
@@ -354,6 +365,18 @@
this.connection.end();
};
+StdIOConnection.prototype.flush_offline_queue = function () {
+ var self = this;
+ var offline_queue = this.offline_queue;
+
+ // Reset offline queue
+ this.offline_queue = [];
+ // Attempt to write queued items
+ offline_queue.forEach(function(data) {
+ self.write(data);
+ });
+};
+
StdIOConnection.prototype.write = function(data) {
if (!this.connected) {
this.offline_queue.push(data);
diff --git a/lib/nodejs/lib/thrift/framed_transport.js b/lib/nodejs/lib/thrift/framed_transport.js
index 6947925..f7daa3f 100644
--- a/lib/nodejs/lib/thrift/framed_transport.js
+++ b/lib/nodejs/lib/thrift/framed_transport.js
@@ -19,6 +19,7 @@
var binary = require('./binary');
var InputBufferUnderrunError = require('./input_buffer_underrun_error');
+var THeaderTransport = require('./header_transport');
module.exports = TFramedTransport;
@@ -30,6 +31,8 @@
this.onFlush = callback;
};
+TFramedTransport.prototype = new THeaderTransport();
+
TFramedTransport.receiver = function(callback, seqid) {
var residual = null;
diff --git a/lib/nodejs/lib/thrift/header_protocol.js b/lib/nodejs/lib/thrift/header_protocol.js
new file mode 100644
index 0000000..0c3b0db
--- /dev/null
+++ b/lib/nodejs/lib/thrift/header_protocol.js
@@ -0,0 +1,256 @@
+/*
+ * 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.
+ */
+var util = require('util');
+var TBinaryProtocol = require('./binary_protocol');
+var TCompactProtocol = require('./compact_protocol');
+var THeaderTransport = require('./header_transport');
+
+var ProtocolMap = {};
+ProtocolMap[THeaderTransport.SubprotocolId.BINARY] = TBinaryProtocol;
+ProtocolMap[THeaderTransport.SubprotocolId.COMPACT] = TCompactProtocol;
+
+module.exports = THeaderProtocol;
+
+function THeaderProtocolError(message) {
+ Error.call(this);
+ Error.captureStackTrace(this, this.constructor);
+ this.name = this.constructor.name;
+ this.message = message;
+}
+
+util.inherits(THeaderProtocolError, Error);
+
+/**
+ * A framed protocol with headers.
+ *
+ * THeaderProtocol frames other Thrift protocols and adds support for
+ * optional out-of-band headers. The currently supported subprotocols are
+ * TBinaryProtocol and TCompactProtocol. It can currently only be used with
+ * transports that inherit THeaderTransport.
+ *
+ * THeaderProtocol does not currently support THTTPServer, TNonblockingServer,
+ * or TProcessPoolServer.
+ *
+ * See doc/specs/HeaderFormat.md for details of the wire format.
+ */
+function THeaderProtocol(trans) {
+ if (!(trans instanceof THeaderTransport)) {
+ throw new THeaderProtocolError(
+ 'Only transports that inherit THeaderTransport can be' +
+ ' used with THeaderProtocol'
+ );
+ }
+ this.trans = trans;
+ this.setProtocol();
+};
+
+THeaderProtocol.prototype.flush = function() {
+ // Headers must be written prior to flushing because because
+ // you need to calculate the length of the payload for the length
+ // field of the header
+ this.trans.writeHeaders();
+ return this.trans.flush();
+};
+
+THeaderProtocol.prototype.writeMessageBegin = function(name, type, seqid) {
+ return this.protocol.writeMessageBegin(name, type, seqid);
+};
+
+THeaderProtocol.prototype.writeMessageEnd = function() {
+ return this.protocol.writeMessageEnd();
+};
+
+THeaderProtocol.prototype.writeStructBegin = function(name) {
+ return this.protocol.writeStructBegin(name);
+};
+
+THeaderProtocol.prototype.writeStructEnd = function() {
+ return this.protocol.writeStructEnd();
+};
+
+THeaderProtocol.prototype.writeFieldBegin = function(name, type, id) {
+ return this.protocol.writeFieldBegin(name, type, id);
+}
+
+THeaderProtocol.prototype.writeFieldEnd = function() {
+ return this.protocol.writeFieldEnd();
+};
+
+THeaderProtocol.prototype.writeFieldStop = function() {
+ return this.protocol.writeFieldStop();
+};
+
+THeaderProtocol.prototype.writeMapBegin = function(ktype, vtype, size) {
+ return this.protocol.writeMapBegin(ktype, vtype, size);
+};
+
+THeaderProtocol.prototype.writeMapEnd = function() {
+ return this.protocol.writeMapEnd();
+};
+
+THeaderProtocol.prototype.writeListBegin = function(etype, size) {
+ return this.protocol.writeListBegin(etype, size);
+};
+
+THeaderProtocol.prototype.writeListEnd = function() {
+ return this.protocol.writeListEnd();
+};
+
+THeaderProtocol.prototype.writeSetBegin = function(etype, size) {
+ return this.protocol.writeSetBegin(etype, size);
+};
+
+THeaderProtocol.prototype.writeSetEnd = function() {
+ return this.protocol.writeSetEnd();
+};
+
+THeaderProtocol.prototype.writeBool = function(b) {
+ return this.protocol.writeBool(b);
+};
+
+THeaderProtocol.prototype.writeByte = function(b) {
+ return this.protocol.writeByte(b);
+};
+
+THeaderProtocol.prototype.writeI16 = function(i16) {
+ return this.protocol.writeI16(i16);
+};
+
+THeaderProtocol.prototype.writeI32 = function(i32) {
+ return this.protocol.writeI32(i32);
+};
+
+THeaderProtocol.prototype.writeI64 = function(i64) {
+ return this.protocol.writeI64(i64);
+};
+
+THeaderProtocol.prototype.writeDouble = function(dub) {
+ return this.protocol.writeDouble(dub);
+};
+
+THeaderProtocol.prototype.writeStringOrBinary = function(name, encoding, arg) {
+ return this.protocol.writeStringOrBinary(name, encoding, arg);
+};
+
+THeaderProtocol.prototype.writeString = function(arg) {
+ return this.protocol.writeString(arg);
+};
+
+THeaderProtocol.prototype.writeBinary = function(arg) {
+ return this.protocol.writeBinary(arg);
+};
+
+THeaderProtocol.prototype.readMessageBegin = function() {
+ this.trans.readHeaders();
+ this.setProtocol();
+ return this.protocol.readMessageBegin();
+};
+
+THeaderProtocol.prototype.readMessageEnd = function() {
+ return this.protocol.readMessageEnd();
+};
+
+THeaderProtocol.prototype.readStructBegin = function() {
+ return this.protocol.readStructBegin();
+};
+
+THeaderProtocol.prototype.readStructEnd = function() {
+ return this.protocol.readStructEnd();
+};
+
+THeaderProtocol.prototype.readFieldBegin = function() {
+ return this.protocol.readFieldBegin();
+};
+
+THeaderProtocol.prototype.readFieldEnd = function() {
+ return this.protocol.readFieldEnd();
+};
+
+THeaderProtocol.prototype.readMapBegin = function() {
+ return this.protocol.readMapBegin();
+};
+
+THeaderProtocol.prototype.readMapEnd = function() {
+ return this.protocol.readMapEnd();
+};
+
+THeaderProtocol.prototype.readListBegin = function() {
+ return this.protocol.readListBegin();
+};
+
+THeaderProtocol.prototype.readListEnd = function() {
+ return this.protocol.readListEnd();
+};
+
+THeaderProtocol.prototype.readSetBegin = function() {
+ return this.protocol.readSetBegin();
+};
+
+THeaderProtocol.prototype.readSetEnd = function() {
+ return this.protocol.readSetEnd();
+};
+
+THeaderProtocol.prototype.readBool = function() {
+ return this.protocol.readBool();
+};
+
+THeaderProtocol.prototype.readByte = function() {
+ return this.protocol.readByte();
+};
+
+THeaderProtocol.prototype.readI16 = function() {
+ return this.protocol.readI16();
+};
+
+THeaderProtocol.prototype.readI32 = function() {
+ return this.protocol.readI32();
+};
+
+THeaderProtocol.prototype.readI64 = function() {
+ return this.protocol.readI64();
+};
+
+THeaderProtocol.prototype.readDouble = function() {
+ return this.protocol.readDouble();
+};
+
+THeaderProtocol.prototype.readBinary = function() {
+ return this.protocol.readBinary();
+};
+
+THeaderProtocol.prototype.readString = function() {
+ return this.protocol.readString();
+};
+
+THeaderProtocol.prototype.getTransport = function() {
+ return this.trans;
+};
+
+THeaderProtocol.prototype.skip = function(type) {
+ return this.protocol.skip(type);
+};
+
+THeaderProtocol.prototype.setProtocol = function(subProtocolId) {
+ var subProtocolId = this.trans.getProtocolId();
+ if (!ProtocolMap[subProtocolId]) {
+ throw new THeaderProtocolError('Headers not supported for protocol ' + subProtocolId);
+ }
+
+ this.protocol = new ProtocolMap[subProtocolId](this.trans);
+};
diff --git a/lib/nodejs/lib/thrift/header_transport.js b/lib/nodejs/lib/thrift/header_transport.js
new file mode 100644
index 0000000..c5f133e
--- /dev/null
+++ b/lib/nodejs/lib/thrift/header_transport.js
@@ -0,0 +1,339 @@
+/*
+ * 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.
+ */
+
+var util = require('util');
+var TCompactProtocol = require('./compact_protocol');
+var TBinaryProtocol = require('./binary_protocol');
+var InputBufferUnderrunError = require('./input_buffer_underrun_error');
+
+function THeaderTransportError(message) {
+ Error.call(this);
+ Error.captureStackTrace(this, this.constructor);
+ this.name = this.constructor.name;
+ this.message = message;
+}
+
+util.inherits(THeaderTransportError, Error);
+
+module.exports = THeaderTransport;
+
+// from HeaderFormat.md
+var COMPACT_PROTOCOL_OFFSET = 0;
+var COMPACT_PROTOCOL_VERSION_OFFSET = 1;
+var FRAME_SIZE_OFFSET = 0;
+var HEADER_MAGIC_OFFSET = 32 / 8;
+var FLAGS_OFFSET = 48 / 8;
+var SEQID_OFFSET = 64 / 8;
+var HEADER_SIZE_OFFSET = 96 / 8;
+var HEADER_START_OFFSET = 112 / 8;
+
+var HEADER_MAGIC = 0x0FFF;
+
+var TINFO_HEADER_KEY_VALUE_TYPE = 0x01;
+var MAX_FRAME_SIZE = 0x3FFFFFFF;
+
+ // A helper class for reading/writing varints. Uses
+ // TCompactProtocol under the hood
+function VarintHelper(readBuffer) {
+ var TBufferedTransport = require('./buffered_transport');
+ this.outputBuffer = null;
+ var _this = this;
+ this.transport = new TBufferedTransport(null, function(output) {
+ _this.outputBuffer = output;
+ });
+
+ this.transport.inBuf = readBuffer || Buffer.alloc(0);
+ this.transport.writeCursor = this.transport.inBuf.length;
+ this.protocol = new TCompactProtocol(this.transport);
+};
+
+VarintHelper.prototype.readVarint32 = function() {
+ return this.protocol.readVarint32();
+};
+
+VarintHelper.prototype.writeVarint32 = function(i) {
+ this.protocol.writeVarint32(i);
+};
+
+VarintHelper.prototype.readString = function() {
+ return this.protocol.readString();
+};
+
+VarintHelper.prototype.writeString = function(str) {
+ this.protocol.writeString(str);
+}
+
+VarintHelper.prototype.getOutCount = function() {
+ return this.transport.outCount;
+};
+
+VarintHelper.prototype.write = function(str) {
+ this.transport.write(str);
+};
+
+VarintHelper.prototype.toBuffer = function() {
+ this.transport.flush();
+ return this.outputBuffer;
+};
+
+// from lib/cpp/src/thrift/protocol/TProtocolTypes.h
+THeaderTransport.SubprotocolId = {
+ BINARY: 0,
+ JSON: 1,
+ COMPACT: 2,
+};
+
+/**
+ An abstract transport used as a prototype for other transports
+ to enable reading/writing theaders. This should NOT be used as a standalone transport
+ The methods in this transport are called by THeaderProtocol, which will call readHeaders/writeHeaders
+ in the read/writeMessageBegin methods and parse/write headers to/from a request
+ prior to reading/writing.
+
+ The reason this is not a standalone transport type is because different transport types
+ have their own individual static receiver methods that are called prior to instantiation.
+ There doesn't seem to be a way for THeaderTransport to know which receiver method to use
+ without reworking the server API.
+
+ For reading headers from a request, the parsed headers can be retrieved via
+ getReadHeader. Similarly, you can set headers to be written on the client via
+ setWriteHeader.
+ */
+function THeaderTransport() {
+ this.maxFrameSize = MAX_FRAME_SIZE;
+ this.protocolId = THeaderTransport.SubprotocolId.BINARY;
+ this.rheaders = {};
+ this.wheaders = {};
+ this.inBuf = Buffer.alloc(0);
+ this.outCount = 0;
+ this.flags = null;
+ this.seqid = 0;
+ this.shouldWriteHeaders = true;
+};
+
+var validateHeaders = function(key, value) {
+ if (typeof key !== 'string' || typeof value !== 'string') {
+ throw new THeaderTransportError('Header key and values must be strings');
+ }
+};
+
+var validateProtocolId = function(protocolId) {
+ var protocols = Object.keys(THeaderTransport.SubprotocolId);
+ for (var i = 0; i < protocols.length; i++) {
+ if (protocolId === THeaderTransport.SubprotocolId[protocols[i]]) return true;
+ }
+
+ throw new Error(protocolId + ' is not a valid protocol id');
+};
+
+THeaderTransport.prototype.setSeqId = function(seqid) {
+ this.seqid = seqid;
+};
+
+THeaderTransport.prototype.getSeqId = function(seqid) {
+ return this.seqid;
+};
+
+THeaderTransport.prototype.setFlags = function(flags) {
+ this.flags = flags;
+};
+
+THeaderTransport.prototype.getReadHeaders = function() {
+ return this.rheaders;
+};
+
+THeaderTransport.prototype.setReadHeader = function(key, value) {
+ validateHeaders(key, value);
+ this.rheaders[key] = value;
+};
+
+THeaderTransport.prototype.clearReadHeaders = function() {
+ this.rheaders = {};
+};
+
+THeaderTransport.prototype.getWriteHeaders = function() {
+ return this.wheaders;
+};
+
+THeaderTransport.prototype.setWriteHeader = function(key, value) {
+ validateHeaders(key, value);
+ this.wheaders[key] = value;
+};
+
+THeaderTransport.prototype.clearWriteHeaders = function() {
+ this.wheaders = {};
+};
+
+THeaderTransport.prototype.setMaxFrameSize = function(frameSize) {
+ this.maxFrameSize = frameSize;
+};
+
+THeaderTransport.prototype.setProtocolId = function(protocolId) {
+ validateProtocolId(protocolId);
+ this.protocolId = protocolId;
+};
+
+THeaderTransport.prototype.getProtocolId = function() {
+ return this.protocolId;
+};
+
+var isUnframedBinary = function(readBuffer) {
+ var version = readBuffer.readInt32BE();
+ return (version & TBinaryProtocol.VERSION_MASK) === TBinaryProtocol.VERSION_1;
+}
+
+var isUnframedCompact = function(readBuffer) {
+ var protocolId = readBuffer.readInt8(COMPACT_PROTOCOL_OFFSET);
+ var version = readBuffer.readInt8(COMPACT_PROTOCOL_VERSION_OFFSET);
+ return protocolId === TCompactProtocol.PROTOCOL_ID &&
+ (version & TCompactProtocol.VERSION_MASK) === TCompactProtocol.VERSION_N;
+}
+
+THeaderTransport.prototype.readHeaders = function() {
+ var readBuffer = this.inBuf;
+
+ var isUnframed = false;
+ if (isUnframedBinary(readBuffer)) {
+ this.setProtocolId(THeaderTransport.SubprotocolId.BINARY);
+ isUnframed = true;
+ }
+
+ if (isUnframedCompact(readBuffer)) {
+ this.setProtocolId(THeaderTransport.SubprotocolId.COMPACT);
+ isUnframed = true;
+ }
+
+ if (isUnframed) {
+ this.shouldWriteHeaders = false;
+ return;
+ }
+
+ var frameSize = readBuffer.readInt32BE(FRAME_SIZE_OFFSET);
+ if (frameSize > this.maxFrameSize) {
+ throw new THeaderTransportError('Frame exceeds maximum frame size');
+ }
+
+ var headerMagic = readBuffer.readInt16BE(HEADER_MAGIC_OFFSET);
+ this.shouldWriteHeaders = headerMagic === HEADER_MAGIC;
+ if (!this.shouldWriteHeaders) {
+ return;
+ }
+
+ this.setFlags(readBuffer.readInt16BE(FLAGS_OFFSET));
+ this.setSeqId(readBuffer.readInt32BE(SEQID_OFFSET));
+ var headerSize = readBuffer.readInt16BE(HEADER_SIZE_OFFSET) * 4;
+ var endOfHeaders = HEADER_START_OFFSET + headerSize;
+ if (endOfHeaders > readBuffer.length) {
+ throw new THeaderTransportError('Header size is greater than frame size');
+ }
+
+ var headerBuffer = Buffer.alloc(headerSize);
+ readBuffer.copy(headerBuffer, 0, HEADER_START_OFFSET, endOfHeaders);
+
+ var varintHelper = new VarintHelper(headerBuffer);
+ this.setProtocolId(varintHelper.readVarint32());
+ var transformCount = varintHelper.readVarint32();
+ if (transformCount > 0) {
+ throw new THeaderTransportError('Transforms are not yet supported');
+ }
+
+ while (true) {
+ try {
+ var headerType = varintHelper.readVarint32();
+ if (headerType !== TINFO_HEADER_KEY_VALUE_TYPE) {
+ break;
+ }
+
+ var numberOfHeaders = varintHelper.readVarint32();
+ for (var i = 0; i < numberOfHeaders; i++) {
+ var key = varintHelper.readString();
+ var value = varintHelper.readString();
+ this.setReadHeader(key, value);
+ }
+ } catch (e) {
+ if (e instanceof InputBufferUnderrunError) {
+ break;
+ }
+ throw e;
+ }
+ }
+
+ // moves the read cursor past the headers
+ this.read(endOfHeaders);
+ return this.getReadHeaders();
+};
+
+THeaderTransport.prototype.writeHeaders = function() {
+ // only write headers on the server if the client contained headers
+ if (!this.shouldWriteHeaders) {
+ return;
+ }
+ var headers = this.getWriteHeaders();
+
+ var varintWriter = new VarintHelper();
+ varintWriter.writeVarint32(this.protocolId);
+ varintWriter.writeVarint32(0); // transforms not supported
+
+ // writing info header key values
+ var headerKeys = Object.keys(headers);
+ if (headerKeys.length > 0) {
+ varintWriter.writeVarint32(TINFO_HEADER_KEY_VALUE_TYPE);
+ varintWriter.writeVarint32(headerKeys.length);
+ for (var i = 0; i < headerKeys.length; i++) {
+ var key = headerKeys[i];
+ var value = headers[key];
+
+ varintWriter.writeString(key);
+ varintWriter.writeString(value);
+ }
+ }
+ var headerSizeWithoutPadding = varintWriter.getOutCount();
+ var paddingNeeded = (4 - (headerSizeWithoutPadding % 4)) % 4;
+
+ var headerSize = Buffer.alloc(2);
+ headerSize.writeInt16BE(Math.floor((headerSizeWithoutPadding + paddingNeeded) / 4));
+
+ var paddingBuffer = Buffer.alloc(paddingNeeded);
+ paddingBuffer.fill(0x00);
+ varintWriter.write(paddingBuffer);
+ var headerContentBuffer = varintWriter.toBuffer();
+ var frameSize = Buffer.alloc(4);
+ frameSize.writeInt32BE(10 + this.outCount + headerContentBuffer.length);
+ var headerMagic = Buffer.alloc(2);
+ headerMagic.writeInt16BE(HEADER_MAGIC);
+
+ // flags are not yet supported, so write a zero
+ var flags = Buffer.alloc(2);
+ flags.writeInt16BE(0);
+
+ var seqid = Buffer.alloc(4);
+ seqid.writeInt32BE(this.getSeqId());
+
+ var headerBuffer = Buffer.concat([
+ frameSize,
+ headerMagic,
+ flags,
+ seqid,
+ headerSize,
+ headerContentBuffer,
+ ]);
+
+ this.outBuffers.unshift(headerBuffer);
+ this.outCount += headerBuffer.length;
+};
diff --git a/lib/nodejs/lib/thrift/index.js b/lib/nodejs/lib/thrift/index.js
index b09953d..0a2d02b 100644
--- a/lib/nodejs/lib/thrift/index.js
+++ b/lib/nodejs/lib/thrift/index.js
@@ -72,3 +72,4 @@
exports.TBinaryProtocol = require('./binary_protocol');
exports.TJSONProtocol = require('./json_protocol');
exports.TCompactProtocol = require('./compact_protocol');
+exports.THeaderProtocol = require('./header_protocol');
diff --git a/lib/nodejs/lib/thrift/server.js b/lib/nodejs/lib/thrift/server.js
index e124acc..16b74ea 100644
--- a/lib/nodejs/lib/thrift/server.js
+++ b/lib/nodejs/lib/thrift/server.js
@@ -23,6 +23,7 @@
var TBufferedTransport = require('./buffered_transport');
var TBinaryProtocol = require('./binary_protocol');
+var THeaderProtocol = require('./header_protocol');
var InputBufferUnderrunError = require('./input_buffer_underrun_error');
/**
@@ -43,14 +44,23 @@
});
stream.on('data', transport.receiver(function(transportWithData) {
var input = new protocol(transportWithData);
- var output = new protocol(new transport(undefined, function(buf) {
+ var outputCb = function(buf) {
try {
stream.write(buf);
} catch (err) {
self.emit('error', err);
stream.end();
}
- }));
+ };
+
+ var output = new protocol(new transport(undefined, outputCb));
+ // Read and write need to be performed on the same transport
+ // for THeaderProtocol because we should only respond with
+ // headers if the request contains headers
+ if (protocol === THeaderProtocol) {
+ output = input;
+ output.trans.onFlush = outputCb;
+ }
try {
do {
diff --git a/lib/nodejs/test/header.test.js b/lib/nodejs/test/header.test.js
new file mode 100644
index 0000000..efd7f81
--- /dev/null
+++ b/lib/nodejs/test/header.test.js
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+const TFramedTransport = require("../lib/thrift/framed_transport");
+const THeaderTransport = require("../lib/thrift/header_transport");
+const THeaderProtocol = require("../lib/thrift/header_protocol");
+const thrift = require("../lib/thrift");
+const fs = require("fs");
+const test = require("tape");
+const path = require("path");
+
+const headerPayload = fs.readFileSync(
+ path.join(__dirname, "test_header_payload")
+);
+
+const cases = {
+ "Should read headers from payload": function(assert) {
+ const transport = new TFramedTransport();
+ transport.inBuf = Buffer.from(headerPayload);
+
+ const headers = transport.readHeaders();
+ assert.equals(headers.Parent, "shoobar");
+ assert.equals(headers.Trace, "abcde");
+ assert.end();
+ },
+ "Should read headers when reading message begin": function(assert) {
+ const transport = new TFramedTransport();
+ transport.inBuf = Buffer.from(headerPayload);
+ const protocol = new THeaderProtocol(transport);
+ const result = protocol.readMessageBegin();
+
+ const headers = transport.getReadHeaders();
+ assert.equals(headers.Parent, "shoobar");
+ assert.equals(headers.Trace, "abcde");
+ assert.equals(result.fname, "add");
+ assert.equals(result.mtype, thrift.Thrift.MessageType.CALL);
+ assert.end();
+ },
+ "Should be able to write headers": function(assert) {
+ const writeTransport = new TFramedTransport();
+ writeTransport.setProtocolId(THeaderTransport.SubprotocolId.BINARY);
+ writeTransport.setWriteHeader("Hihihihi", "hohohoho");
+ writeTransport.setWriteHeader("boobooboo", "fooshoopoo");
+ writeTransport.setWriteHeader("a", "z");
+ writeTransport.writeHeaders();
+ const writeBuffer = writeTransport.outBuffers[0];
+
+ const readTransport = new TFramedTransport();
+ readTransport.inBuf = writeBuffer;
+ readTransport.readHeaders();
+
+ const headers = readTransport.getReadHeaders();
+ assert.equals(headers.Hihihihi, "hohohoho");
+ assert.equals(headers.boobooboo, "fooshoopoo");
+ assert.equals(headers.a, "z");
+ assert.end();
+ }
+};
+
+Object.keys(cases).forEach(function(caseName) {
+ test(caseName, cases[caseName]);
+});
diff --git a/lib/nodejs/test/helpers.js b/lib/nodejs/test/helpers.js
index 72d128d..f3c27b3 100644
--- a/lib/nodejs/test/helpers.js
+++ b/lib/nodejs/test/helpers.js
@@ -28,7 +28,8 @@
module.exports.protocols = {
json: thrift.TJSONProtocol,
binary: thrift.TBinaryProtocol,
- compact: thrift.TCompactProtocol
+ compact: thrift.TCompactProtocol,
+ header: thrift.THeaderProtocol
};
module.exports.ecmaMode = process.argv.includes("--es6") ? "es6" : "es5";
diff --git a/lib/nodejs/test/int64.test.js b/lib/nodejs/test/int64.test.js
new file mode 100644
index 0000000..27ad28c
--- /dev/null
+++ b/lib/nodejs/test/int64.test.js
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+const Int64 = require("node-int64");
+const JSONInt64 = require("json-int64");
+const i64types = require("./gen-nodejs-es6/Int64Test_types.js");
+const test = require("tape");
+
+const cases = {
+ "should correctly generate Int64 constants": function(assert) {
+ const EXPECTED_SMALL_INT64_AS_NUMBER = 42;
+ const EXPECTED_SMALL_INT64 = new Int64(42);
+ const EXPECTED_MAX_JS_SAFE_INT64 = new Int64(Number.MAX_SAFE_INTEGER);
+ const EXPECTED_MIN_JS_SAFE_INT64 = new Int64(Number.MIN_SAFE_INTEGER);
+ const EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64 = new Int64("0020000000000000"); // hex-encoded
+ const EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64 = new Int64("ffe0000000000000"); // hex-encoded 2's complement
+ const EXPECTED_MAX_SIGNED_INT64 = new Int64("7fffffffffffffff"); // hex-encoded
+ const EXPECTED_MIN_SIGNED_INT64 = new Int64("8000000000000000"); // hex-encoded 2's complement
+ const EXPECTED_INT64_LIST = [
+ EXPECTED_SMALL_INT64,
+ EXPECTED_MAX_JS_SAFE_INT64,
+ EXPECTED_MIN_JS_SAFE_INT64,
+ EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64,
+ EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64,
+ EXPECTED_MAX_SIGNED_INT64,
+ EXPECTED_MIN_SIGNED_INT64
+ ];
+
+ assert.ok(EXPECTED_SMALL_INT64.equals(i64types.SMALL_INT64));
+ assert.ok(EXPECTED_MAX_JS_SAFE_INT64.equals(i64types.MAX_JS_SAFE_INT64));
+ assert.ok(EXPECTED_MIN_JS_SAFE_INT64.equals(i64types.MIN_JS_SAFE_INT64));
+ assert.ok(
+ EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64.equals(
+ i64types.MAX_JS_SAFE_PLUS_ONE_INT64
+ )
+ );
+ assert.ok(
+ EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64.equals(
+ i64types.MIN_JS_SAFE_MINUS_ONE_INT64
+ )
+ );
+ assert.ok(EXPECTED_MAX_SIGNED_INT64.equals(i64types.MAX_SIGNED_INT64));
+ assert.ok(EXPECTED_MIN_SIGNED_INT64.equals(i64types.MIN_SIGNED_INT64));
+ assert.equal(
+ EXPECTED_SMALL_INT64_AS_NUMBER,
+ i64types.SMALL_INT64.toNumber()
+ );
+ assert.equal(
+ Number.MAX_SAFE_INTEGER,
+ i64types.MAX_JS_SAFE_INT64.toNumber()
+ );
+ assert.equal(
+ Number.MIN_SAFE_INTEGER,
+ i64types.MIN_JS_SAFE_INT64.toNumber()
+ );
+
+ for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) {
+ assert.ok(EXPECTED_INT64_LIST[i].equals(i64types.INT64_LIST[i]));
+ }
+
+ for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) {
+ const int64Object = EXPECTED_INT64_LIST[i];
+ assert.ok(
+ i64types.INT64_2_INT64_MAP[
+ JSONInt64.toDecimalString(int64Object)
+ ].equals(int64Object)
+ );
+ }
+
+ assert.end();
+ }
+};
+
+Object.keys(cases).forEach(function(caseName) {
+ test(caseName, cases[caseName]);
+});
diff --git a/lib/nodejs/test/testAll.sh b/lib/nodejs/test/testAll.sh
index 24f1f2e..e98b198 100755
--- a/lib/nodejs/test/testAll.sh
+++ b/lib/nodejs/test/testAll.sh
@@ -61,13 +61,16 @@
${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node ${DIR}/../../../test/ThriftTest.thrift
${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node ${DIR}/../../../test/JsDeepConstructorTest.thrift
+${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node ${DIR}/../../../test/Int64Test.thrift
mkdir ${DIR}/gen-nodejs-es6
${DIR}/../../../compiler/cpp/thrift -out ${DIR}/gen-nodejs-es6 --gen js:node,es6 ${DIR}/../../../test/ThriftTest.thrift
${DIR}/../../../compiler/cpp/thrift -out ${DIR}/gen-nodejs-es6 --gen js:node,es6 ${DIR}/../../../test/JsDeepConstructorTest.thrift
+${DIR}/../../../compiler/cpp/thrift -out ${DIR}/gen-nodejs-es6 --gen js:node,es6 ${DIR}/../../../test/Int64Test.thrift
#unit tests
node ${DIR}/binary.test.js || TESTOK=1
+node ${DIR}/int64.test.js || TESTOK=1
node ${DIR}/deep-constructor.test.js || TESTOK=1
#integration tests
diff --git a/lib/nodejs/test/test_header_payload b/lib/nodejs/test/test_header_payload
new file mode 100644
index 0000000..22d5ef7
--- /dev/null
+++ b/lib/nodejs/test/test_header_payload
Binary files differ
diff --git a/lib/nodets/Makefile.am b/lib/nodets/Makefile.am
index ea640cf..939dff2 100755
--- a/lib/nodets/Makefile.am
+++ b/lib/nodets/Makefile.am
@@ -20,6 +20,7 @@
stubs: $(top_srcdir)/test/ThriftTest.thrift
mkdir -p test-compiled
$(THRIFT) --gen js:node,ts -o test/ $(top_srcdir)/test/ThriftTest.thrift && $(THRIFT) --gen js:node,ts -o test-compiled $(top_srcdir)/test/ThriftTest.thrift
+ $(THRIFT) --gen js:node,ts -o test/ $(top_srcdir)/test/Int64Test.thrift && $(THRIFT) --gen js:node,ts -o test-compiled $(top_srcdir)/test/Int64Test.thrift
ts-compile: stubs
mkdir -p test-compiled
diff --git a/lib/nodets/test/int64.test.ts b/lib/nodets/test/int64.test.ts
new file mode 100644
index 0000000..d209234
--- /dev/null
+++ b/lib/nodets/test/int64.test.ts
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+import Int64 = require("node-int64");
+import JSONInt64 = require('json-int64');
+import i64types = require("./gen-nodejs/Int64Test_types");
+import test = require("tape");
+
+const cases = {
+ "should correctly generate Int64 constants": function(assert) {
+ const EXPECTED_SMALL_INT64_AS_NUMBER: number = 42;
+ const EXPECTED_SMALL_INT64: Int64 = new Int64(42);
+ const EXPECTED_MAX_JS_SAFE_INT64: Int64 = new Int64(Number.MAX_SAFE_INTEGER);
+ const EXPECTED_MIN_JS_SAFE_INT64: Int64 = new Int64(Number.MIN_SAFE_INTEGER);
+ const EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64: Int64 = new Int64("0020000000000000"); // hex-encoded
+ const EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64: Int64 = new Int64("ffe0000000000000"); // hex-encoded 2's complement
+ const EXPECTED_MAX_SIGNED_INT64: Int64 = new Int64("7fffffffffffffff"); // hex-encoded
+ const EXPECTED_MIN_SIGNED_INT64: Int64 = new Int64("8000000000000000"); // hex-encoded 2's complement
+ const EXPECTED_INT64_LIST: Int64[] = [
+ EXPECTED_SMALL_INT64,
+ EXPECTED_MAX_JS_SAFE_INT64,
+ EXPECTED_MIN_JS_SAFE_INT64,
+ EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64,
+ EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64,
+ EXPECTED_MAX_SIGNED_INT64,
+ EXPECTED_MIN_SIGNED_INT64
+ ];
+
+ assert.ok(EXPECTED_SMALL_INT64.equals(i64types.SMALL_INT64));
+ assert.ok(EXPECTED_MAX_JS_SAFE_INT64.equals(i64types.MAX_JS_SAFE_INT64));
+ assert.ok(EXPECTED_MIN_JS_SAFE_INT64.equals(i64types.MIN_JS_SAFE_INT64));
+ assert.ok(
+ EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64.equals(
+ i64types.MAX_JS_SAFE_PLUS_ONE_INT64
+ )
+ );
+ assert.ok(
+ EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64.equals(
+ i64types.MIN_JS_SAFE_MINUS_ONE_INT64
+ )
+ );
+ assert.ok(EXPECTED_MAX_SIGNED_INT64.equals(i64types.MAX_SIGNED_INT64));
+ assert.ok(EXPECTED_MIN_SIGNED_INT64.equals(i64types.MIN_SIGNED_INT64));
+ assert.equal(
+ EXPECTED_SMALL_INT64_AS_NUMBER,
+ i64types.SMALL_INT64.toNumber()
+ );
+ assert.equal(
+ Number.MAX_SAFE_INTEGER,
+ i64types.MAX_JS_SAFE_INT64.toNumber()
+ );
+ assert.equal(
+ Number.MIN_SAFE_INTEGER,
+ i64types.MIN_JS_SAFE_INT64.toNumber()
+ );
+
+ for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) {
+ assert.ok(EXPECTED_INT64_LIST[i].equals(i64types.INT64_LIST[i]));
+ }
+
+ for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i){
+ let int64Object = EXPECTED_INT64_LIST[i];
+ assert.ok(i64types.INT64_2_INT64_MAP[JSONInt64.toDecimalString(int64Object)].equals(int64Object));
+ }
+
+ assert.end();
+ }
+};
+
+Object.keys(cases).forEach(function(caseName) {
+ test(caseName, cases[caseName]);
+});
diff --git a/lib/nodets/test/test-cases.ts b/lib/nodets/test/test-cases.ts
index ca740ec..44f254e 100644
--- a/lib/nodets/test/test-cases.ts
+++ b/lib/nodets/test/test-cases.ts
@@ -1,6 +1,7 @@
'use strict';
import ttypes = require('./gen-nodejs/ThriftTest_types');
+import Int64 = require('node-int64');
//all Languages in UTF-8
/*jshint -W100 */
@@ -84,7 +85,7 @@
string_thing: 'Zero',
byte_thing: 1,
i32_thing: -3,
- i64_thing: 1000000
+ i64_thing: new Int64(1000000)
});
export var out2 = new ttypes.Xtruct2();
@@ -93,17 +94,17 @@
out2.i32_thing = 5;
export var crazy = new ttypes.Insanity({
- "userMap":{ "5":5, "8":8 },
+ "userMap":{ "5":new Int64(5), "8":new Int64(8) },
"xtructs":[new ttypes.Xtruct({
"string_thing":"Goodbye4",
"byte_thing":4,
"i32_thing":4,
- "i64_thing":4
+ "i64_thing":new Int64(4)
}), new ttypes.Xtruct({
"string_thing":"Hello2",
"byte_thing":2,
"i32_thing":2,
- "i64_thing":2
+ "i64_thing":new Int64(2)
})]
});
diff --git a/lib/nodets/test/testAll.sh b/lib/nodets/test/testAll.sh
index a7c00bf..3be12c3 100755
--- a/lib/nodets/test/testAll.sh
+++ b/lib/nodets/test/testAll.sh
@@ -11,7 +11,9 @@
{
#generating thrift code
${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node,ts ${DIR}/../../../test/ThriftTest.thrift
+ ${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node,ts ${DIR}/../../../test/Int64Test.thrift
${DIR}/../../../compiler/cpp/thrift -o ${COMPILEDDIR} --gen js:node,ts ${DIR}/../../../test/ThriftTest.thrift
+ ${DIR}/../../../compiler/cpp/thrift -o ${COMPILEDDIR} --gen js:node,ts ${DIR}/../../../test/Int64Test.thrift
tsc --outDir $COMPILEDDIR --project $DIR/tsconfig.json
}
@@ -30,6 +32,8 @@
return $RET
}
+node ${COMPILEDDIR}/int64.test.js || TESTOK=1
+
#integration tests
testServer || TESTOK=1
diff --git a/lib/nodets/test/test_handler.ts b/lib/nodets/test/test_handler.ts
index 1bc855a..996c32a 100644
--- a/lib/nodets/test/test_handler.ts
+++ b/lib/nodets/test/test_handler.ts
@@ -24,6 +24,7 @@
import thrift = require("thrift");
import Thrift = thrift.Thrift;
import Q = require("q");
+import Int64 = require("node-int64");
export class SyncThriftTestHandler {
@@ -62,7 +63,7 @@
return Q.resolve(insane);
}
- testMulti(arg0: any, arg1: number, arg2: number, arg3: { [k: number]: string; }, arg4: ttypes.Numberz, arg5: number) {
+ testMulti(arg0: any, arg1: number, arg2: Int64, arg3: { [k: number]: string; }, arg4: ttypes.Numberz, arg5: number) {
var hello = new ttypes.Xtruct();
hello.string_thing = 'Hello2';
hello.byte_thing = arg0;
@@ -196,7 +197,7 @@
}
return Q.resolve();
}
- testMulti(arg0: any, arg1: number, arg2: number, arg3: { [k: number]: string; }, arg4: ttypes.Numberz, arg5: number, result: Function): Q.IPromise<ttypes.Xtruct> {
+ testMulti(arg0: any, arg1: number, arg2: Int64, arg3: { [k: number]: string; }, arg4: ttypes.Numberz, arg5: number, result: Function): Q.IPromise<ttypes.Xtruct> {
var hello = this.syncHandler.testMulti(arg0, arg1, arg2, arg3, arg4, arg5);
hello.then(hello => result(null, hello));
return Q.resolve();
diff --git a/lib/ocaml/_oasis b/lib/ocaml/_oasis
index ed4a88b..83566aa 100644
--- a/lib/ocaml/_oasis
+++ b/lib/ocaml/_oasis
@@ -1,5 +1,5 @@
Name: libthrift-ocaml
-Version: 0.12.1
+Version: 0.13.0
OASISFormat: 0.3
Synopsis: OCaml bindings for the Apache Thrift RPC system
Authors: Apache Thrift Developers <dev@thrift.apache.org>
diff --git a/lib/perl/lib/Thrift.pm b/lib/perl/lib/Thrift.pm
index 71be7d5..01985ea 100644
--- a/lib/perl/lib/Thrift.pm
+++ b/lib/perl/lib/Thrift.pm
@@ -31,6 +31,6 @@
#
package Thrift;
-use version 0.77; our $VERSION = version->declare("v0.12.1");
+use version 0.77; our $VERSION = version->declare("v0.13.0");
1;
diff --git a/lib/php/Makefile.am b/lib/php/Makefile.am
index 8d9050a..7fdebe1 100755
--- a/lib/php/Makefile.am
+++ b/lib/php/Makefile.am
@@ -33,6 +33,7 @@
phpmodule_SCRIPTS = src/ext/thrift_protocol/modules/thrift_protocol.so
distclean-local:
+ if [ -f src/ext/thrift_protocol/Makefile ]; then cd src/ext/thrift_protocol/ && $(MAKE) distclean; fi
cd $(phpmodule_SCRIPTS) && $(PHPIZE) --clean
endif
@@ -128,6 +129,10 @@
lib/Type/TType.php \
lib/Type/TConstant.php
+clean-local:
+ if [ -f src/ext/thrift_protocol/Makefile ]; then cd src/ext/thrift_protocol/ && $(MAKE) clean; fi
+
+
EXTRA_DIST = \
lib \
src/autoload.php \
@@ -144,6 +149,5 @@
README.md
MAINTAINERCLEANFILES = \
- Makefile \
Makefile.in
diff --git a/lib/php/README.md b/lib/php/README.md
index f903c6e..7170104 100644
--- a/lib/php/README.md
+++ b/lib/php/README.md
@@ -53,7 +53,7 @@
# Breaking Changes
-## 0.12.x
+## 0.12.0
1. [PSR-4](https://www.php-fig.org/psr/psr-4/) loader is now the default. If you want to use class maps instead, use `-gen php:classmap`.
diff --git a/lib/php/lib/Protocol/TProtocol.php b/lib/php/lib/Protocol/TProtocol.php
index 81aceb6..f7b581f 100644
--- a/lib/php/lib/Protocol/TProtocol.php
+++ b/lib/php/lib/Protocol/TProtocol.php
@@ -22,6 +22,8 @@
namespace Thrift\Protocol;
+use Thrift\Exception\TException;
+use Thrift\Transport\TTransport;
use Thrift\Type\TType;
use Thrift\Exception\TProtocolException;
@@ -38,7 +40,7 @@
protected $trans_;
/**
- * Constructor
+ * @param TTransport $trans
*/
protected function __construct($trans)
{
diff --git a/lib/php/lib/Transport/TCurlClient.php b/lib/php/lib/Transport/TCurlClient.php
index 482b43b..2060d34 100644
--- a/lib/php/lib/Transport/TCurlClient.php
+++ b/lib/php/lib/Transport/TCurlClient.php
@@ -230,7 +230,12 @@
curl_setopt(self::$curlHandle, CURLOPT_HTTPHEADER, $headers);
if ($this->timeout_ > 0) {
- curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT, $this->timeout_);
+ if ($this->timeout_ < 1.0) {
+ // Timestamps smaller than 1 second are ignored when CURLOPT_TIMEOUT is used
+ curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT_MS, 1000 * $this->timeout_);
+ } else {
+ curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT, $this->timeout_);
+ }
}
curl_setopt(self::$curlHandle, CURLOPT_POSTFIELDS, $this->request_);
$this->request_ = '';
diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp
index 63c8905..e152d08 100644
--- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp
+++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp
@@ -1013,7 +1013,7 @@
zval* prop = zend_read_property(Z_OBJCE_P(zthis), zthis, varname, strlen(varname), false, &rv);
if (Z_TYPE_P(prop) == IS_REFERENCE){
- ZVAL_UNREF(prop);
+ ZVAL_DEREF(prop);
}
if (Z_TYPE_P(prop) != IS_NULL) {
transport.writeI8(ttype);
diff --git a/lib/php/test/Makefile.am b/lib/php/test/Makefile.am
index 4824688..6f4e50a 100755
--- a/lib/php/test/Makefile.am
+++ b/lib/php/test/Makefile.am
@@ -48,6 +48,8 @@
check-validator \
check-json-serializer
+distclean-local:
+
clean-local:
$(RM) -r ./packages
$(RM) TEST-*.xml
diff --git a/lib/py/Makefile.am b/lib/py/Makefile.am
index 5861858..46e4405 100644
--- a/lib/py/Makefile.am
+++ b/lib/py/Makefile.am
@@ -40,13 +40,19 @@
install-exec-hook:
$(PYTHON) setup.py install --root=$(DESTDIR) --prefix=$(PY_PREFIX) $(PYTHON_SETUPUTIL_ARGS)
-clean-local:
- $(RM) -r build
-
check-local: all py3-test
$(PYTHON) test/thrift_json.py
$(PYTHON) test/test_sslsocket.py
+clean-local:
+ $(RM) -r build
+ find . -type f \( -iname "*.pyc" \) | xargs rm -f
+ find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
+
+dist-hook:
+ find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f
+ find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
+
EXTRA_DIST = \
CMakeLists.txt \
MANIFEST.in \
diff --git a/lib/py/setup.py b/lib/py/setup.py
index 2043ab0..2ba2691 100644
--- a/lib/py/setup.py
+++ b/lib/py/setup.py
@@ -90,9 +90,9 @@
twisted_deps = ['twisted']
setup(name='thrift',
- version='0.12.1',
+ version='0.13.0',
description='Python bindings for the Apache Thrift RPC system',
- author='Thrift Developers',
+ author='Apache Thrift Developers',
author_email='dev@thrift.apache.org',
url='http://thrift.apache.org',
license='Apache License 2.0',
diff --git a/lib/py/src/TMultiplexedProcessor.py b/lib/py/src/TMultiplexedProcessor.py
index 3ac5af0..ff88430 100644
--- a/lib/py/src/TMultiplexedProcessor.py
+++ b/lib/py/src/TMultiplexedProcessor.py
@@ -17,33 +17,61 @@
# under the License.
#
-from thrift.Thrift import TProcessor, TMessageType, TException
+from thrift.Thrift import TProcessor, TMessageType
from thrift.protocol import TProtocolDecorator, TMultiplexedProtocol
+from thrift.protocol.TProtocol import TProtocolException
class TMultiplexedProcessor(TProcessor):
def __init__(self):
+ self.defaultProcessor = None
self.services = {}
+ def registerDefault(self, processor):
+ """
+ If a non-multiplexed processor connects to the server and wants to
+ communicate, use the given processor to handle it. This mechanism
+ allows servers to upgrade from non-multiplexed to multiplexed in a
+ backwards-compatible way and still handle old clients.
+ """
+ self.defaultProcessor = processor
+
def registerProcessor(self, serviceName, processor):
self.services[serviceName] = processor
+ def on_message_begin(self, func):
+ for key in self.services.keys():
+ self.services[key].on_message_begin(func)
+
def process(self, iprot, oprot):
(name, type, seqid) = iprot.readMessageBegin()
if type != TMessageType.CALL and type != TMessageType.ONEWAY:
- raise TException("TMultiplexed protocol only supports CALL & ONEWAY")
+ raise TProtocolException(
+ TProtocolException.NOT_IMPLEMENTED,
+ "TMultiplexedProtocol only supports CALL & ONEWAY")
index = name.find(TMultiplexedProtocol.SEPARATOR)
if index < 0:
- raise TException("Service name not found in message name: " + name + ". Did you forget to use TMultiplexedProtocol in your client?")
+ if self.defaultProcessor:
+ return self.defaultProcessor.process(
+ StoredMessageProtocol(iprot, (name, type, seqid)), oprot)
+ else:
+ raise TProtocolException(
+ TProtocolException.NOT_IMPLEMENTED,
+ "Service name not found in message name: " + name + ". " +
+ "Did you forget to use TMultiplexedProtocol in your client?")
serviceName = name[0:index]
call = name[index + len(TMultiplexedProtocol.SEPARATOR):]
if serviceName not in self.services:
- raise TException("Service name not found: " + serviceName + ". Did you forget to call registerProcessor()?")
+ raise TProtocolException(
+ TProtocolException.NOT_IMPLEMENTED,
+ "Service name not found: " + serviceName + ". " +
+ "Did you forget to call registerProcessor()?")
standardMessage = (call, type, seqid)
- return self.services[serviceName].process(StoredMessageProtocol(iprot, standardMessage), oprot)
+ return self.services[serviceName].process(
+ StoredMessageProtocol(iprot, standardMessage), oprot)
class StoredMessageProtocol(TProtocolDecorator.TProtocolDecorator):
diff --git a/lib/py/src/Thrift.py b/lib/py/src/Thrift.py
index 00941d8..c390cbb 100644
--- a/lib/py/src/Thrift.py
+++ b/lib/py/src/Thrift.py
@@ -72,6 +72,18 @@
"""Base class for processor, which works on two streams."""
def process(self, iprot, oprot):
+ """
+ Process a request. The normal behvaior is to have the
+ processor invoke the correct handler and then it is the
+ server's responsibility to write the response to oprot.
+ """
+ pass
+
+ def on_message_begin(self, func):
+ """
+ Install a callback that receives (name, type, seqid)
+ after the message header is read.
+ """
pass
diff --git a/lib/py/src/ext/endian.h b/lib/py/src/ext/endian.h
index 91372a7..1660cbd 100644
--- a/lib/py/src/ext/endian.h
+++ b/lib/py/src/ext/endian.h
@@ -79,6 +79,10 @@
#include <byteswap.h>
#define ntohll(n) bswap_64(n)
#define htonll(n) bswap_64(n)
+#elif defined(_MSC_VER)
+#include <stdlib.h>
+#define ntohll(n) _byteswap_uint64(n)
+#define htonll(n) _byteswap_uint64(n)
#else /* GNUC & GLIBC */
#define ntohll(n) ((((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32))
#define htonll(n) ((((unsigned long long)htonl(n)) << 32) + htonl(n >> 32))
diff --git a/lib/py/src/protocol/TBinaryProtocol.py b/lib/py/src/protocol/TBinaryProtocol.py
index f6be772..6b2facc 100644
--- a/lib/py/src/protocol/TBinaryProtocol.py
+++ b/lib/py/src/protocol/TBinaryProtocol.py
@@ -17,7 +17,7 @@
# under the License.
#
-from .TProtocol import TType, TProtocolBase, TProtocolException
+from .TProtocol import TType, TProtocolBase, TProtocolException, TProtocolFactory
from struct import pack, unpack
@@ -235,7 +235,7 @@
return s
-class TBinaryProtocolFactory(object):
+class TBinaryProtocolFactory(TProtocolFactory):
def __init__(self, strictRead=False, strictWrite=True, **kwargs):
self.strictRead = strictRead
self.strictWrite = strictWrite
@@ -284,7 +284,7 @@
self._fast_encode = fastbinary.encode_binary
-class TBinaryProtocolAcceleratedFactory(object):
+class TBinaryProtocolAcceleratedFactory(TProtocolFactory):
def __init__(self,
string_length_limit=None,
container_length_limit=None,
diff --git a/lib/py/src/protocol/TCompactProtocol.py b/lib/py/src/protocol/TCompactProtocol.py
index e485cff..700e792 100644
--- a/lib/py/src/protocol/TCompactProtocol.py
+++ b/lib/py/src/protocol/TCompactProtocol.py
@@ -17,7 +17,7 @@
# under the License.
#
-from .TProtocol import TType, TProtocolBase, TProtocolException, checkIntegerLimits
+from .TProtocol import TType, TProtocolBase, TProtocolException, TProtocolFactory, checkIntegerLimits
from struct import pack, unpack
from ..compat import binary_to_str, str_to_binary
@@ -58,6 +58,7 @@
def writeVarint(trans, n):
+ assert n >= 0, "Input to TCompactProtocol writeVarint cannot be negative!"
out = bytearray()
while True:
if n & ~0x7f == 0:
@@ -156,7 +157,14 @@
assert self.state == CLEAR
self.__writeUByte(self.PROTOCOL_ID)
self.__writeUByte(self.VERSION | (type << self.TYPE_SHIFT_AMOUNT))
- self.__writeVarint(seqid)
+ # The sequence id is a signed 32-bit integer but the compact protocol
+ # writes this out as a "var int" which is always positive, and attempting
+ # to write a negative number results in an infinite loop, so we may
+ # need to do some conversion here...
+ tseqid = seqid
+ if tseqid < 0:
+ tseqid = 2147483648 + (2147483648 + tseqid)
+ self.__writeVarint(tseqid)
self.__writeBinary(str_to_binary(name))
self.state = VALUE_WRITE
@@ -334,6 +342,10 @@
raise TProtocolException(TProtocolException.BAD_VERSION,
'Bad version: %d (expect %d)' % (version, self.VERSION))
seqid = self.__readVarint()
+ # the sequence is a compact "var int" which is treaded as unsigned,
+ # however the sequence is actually signed...
+ if seqid > 2147483647:
+ seqid = -2147483648 - (2147483648 - seqid)
name = binary_to_str(self.__readBinary())
return (name, type, seqid)
@@ -416,7 +428,7 @@
return TTYPES[byte & 0x0f]
-class TCompactProtocolFactory(object):
+class TCompactProtocolFactory(TProtocolFactory):
def __init__(self,
string_length_limit=None,
container_length_limit=None):
@@ -458,7 +470,7 @@
self._fast_encode = fastbinary.encode_compact
-class TCompactProtocolAcceleratedFactory(object):
+class TCompactProtocolAcceleratedFactory(TProtocolFactory):
def __init__(self,
string_length_limit=None,
container_length_limit=None,
diff --git a/lib/py/src/protocol/THeaderProtocol.py b/lib/py/src/protocol/THeaderProtocol.py
index b27a749..13982e8 100644
--- a/lib/py/src/protocol/THeaderProtocol.py
+++ b/lib/py/src/protocol/THeaderProtocol.py
@@ -19,7 +19,7 @@
from thrift.protocol.TBinaryProtocol import TBinaryProtocolAccelerated
from thrift.protocol.TCompactProtocol import TCompactProtocolAccelerated
-from thrift.protocol.TProtocol import TProtocolBase, TProtocolException
+from thrift.protocol.TProtocol import TProtocolBase, TProtocolException, TProtocolFactory
from thrift.Thrift import TApplicationException, TMessageType
from thrift.transport.THeaderTransport import THeaderTransport, THeaderSubprotocolID, THeaderClientType
@@ -217,7 +217,7 @@
return self._protocol.readBinary()
-class THeaderProtocolFactory(object):
+class THeaderProtocolFactory(TProtocolFactory):
def __init__(self, allowed_client_types=(THeaderClientType.HEADERS,)):
self.allowed_client_types = allowed_client_types
diff --git a/lib/py/src/protocol/TJSONProtocol.py b/lib/py/src/protocol/TJSONProtocol.py
index db2099a..1741702 100644
--- a/lib/py/src/protocol/TJSONProtocol.py
+++ b/lib/py/src/protocol/TJSONProtocol.py
@@ -18,7 +18,7 @@
#
from .TProtocol import (TType, TProtocolBase, TProtocolException,
- checkIntegerLimits)
+ TProtocolFactory, checkIntegerLimits)
import base64
import math
import sys
@@ -577,7 +577,7 @@
self.writeJSONBase64(binary)
-class TJSONProtocolFactory(object):
+class TJSONProtocolFactory(TProtocolFactory):
def getProtocol(self, trans):
return TJSONProtocol(trans)
@@ -671,7 +671,7 @@
self.writeJSONBase64(binary)
-class TSimpleJSONProtocolFactory(object):
+class TSimpleJSONProtocolFactory(TProtocolFactory):
def getProtocol(self, trans):
return TSimpleJSONProtocol(trans)
diff --git a/lib/py/src/protocol/__init__.py b/lib/py/src/protocol/__init__.py
index 7148f66..06647a2 100644
--- a/lib/py/src/protocol/__init__.py
+++ b/lib/py/src/protocol/__init__.py
@@ -18,4 +18,4 @@
#
__all__ = ['fastbinary', 'TBase', 'TBinaryProtocol', 'TCompactProtocol',
- 'TJSONProtocol', 'TProtocol']
+ 'TJSONProtocol', 'TProtocol', 'TProtocolDecorator']
diff --git a/lib/py/src/server/THttpServer.py b/lib/py/src/server/THttpServer.py
index 85cf400..47e817d 100644
--- a/lib/py/src/server/THttpServer.py
+++ b/lib/py/src/server/THttpServer.py
@@ -21,6 +21,7 @@
from six.moves import BaseHTTPServer
+from thrift.Thrift import TMessageType
from thrift.server import TServer
from thrift.transport import TTransport
@@ -32,7 +33,9 @@
to override this behavior (e.g., to simulate a misconfigured or
overloaded web server during testing), it can raise a ResponseException.
The function passed to the constructor will be called with the
- RequestHandler as its only argument.
+ RequestHandler as its only argument. Note that this is irrelevant
+ for ONEWAY requests, as the HTTP response must be sent before the
+ RPC is processed.
"""
def __init__(self, handler):
self.handler = handler
@@ -43,6 +46,9 @@
This class is not very performant, but it is useful (for example) for
acting as a mock version of an Apache-based PHP Thrift endpoint.
+ Also important to note the HTTP implementation pretty much violates the
+ transport/protocol/processor/server layering, by performing the transport
+ functions here. This means things like oneway handling are oddly exposed.
"""
def __init__(self,
processor,
@@ -68,26 +74,45 @@
inputProtocolFactory, outputProtocolFactory)
thttpserver = self
+ self._replied = None
class RequestHander(BaseHTTPServer.BaseHTTPRequestHandler):
def do_POST(self):
# Don't care about the request path.
- itrans = TTransport.TFileObjectTransport(self.rfile)
- otrans = TTransport.TFileObjectTransport(self.wfile)
+ thttpserver._replied = False
+ iftrans = TTransport.TFileObjectTransport(self.rfile)
itrans = TTransport.TBufferedTransport(
- itrans, int(self.headers['Content-Length']))
+ iftrans, int(self.headers['Content-Length']))
otrans = TTransport.TMemoryBuffer()
iprot = thttpserver.inputProtocolFactory.getProtocol(itrans)
oprot = thttpserver.outputProtocolFactory.getProtocol(otrans)
try:
+ thttpserver.processor.on_message_begin(self.on_begin)
thttpserver.processor.process(iprot, oprot)
except ResponseException as exn:
exn.handler(self)
else:
+ if not thttpserver._replied:
+ # If the request was ONEWAY we would have replied already
+ data = otrans.getvalue()
+ self.send_response(200)
+ self.send_header("Content-Length", len(data))
+ self.send_header("Content-Type", "application/x-thrift")
+ self.end_headers()
+ self.wfile.write(data)
+
+ def on_begin(self, name, type, seqid):
+ """
+ Inspect the message header.
+
+ This allows us to post an immediate transport response
+ if the request is a ONEWAY message type.
+ """
+ if type == TMessageType.ONEWAY:
self.send_response(200)
- self.send_header("content-type", "application/x-thrift")
+ self.send_header("Content-Type", "application/x-thrift")
self.end_headers()
- self.wfile.write(otrans.getvalue())
+ thttpserver._replied = True
self.httpd = server_class(server_address, RequestHander)
diff --git a/lib/py/src/transport/TSSLSocket.py b/lib/py/src/transport/TSSLSocket.py
index b54ca5d..066d8da 100644
--- a/lib/py/src/transport/TSSLSocket.py
+++ b/lib/py/src/transport/TSSLSocket.py
@@ -79,8 +79,8 @@
SSL_VERSION = _default_protocol
"""
Default SSL version.
- For backword compatibility, it can be modified.
- Use __init__ keywoard argument "ssl_version" instead.
+ For backwards compatibility, it can be modified.
+ Use __init__ keyword argument "ssl_version" instead.
"""
def _deprecated_arg(self, args, kwargs, pos, key):
@@ -89,12 +89,12 @@
real_pos = pos + 3
warnings.warn(
'%dth positional argument is deprecated.'
- 'please use keyward argument insteand.'
+ 'please use keyword argument instead.'
% real_pos, DeprecationWarning, stacklevel=3)
if key in kwargs:
raise TypeError(
- 'Duplicate argument: %dth argument and %s keyward argument.'
+ 'Duplicate argument: %dth argument and %s keyword argument.'
% (real_pos, key))
kwargs[key] = args[pos]
@@ -118,7 +118,7 @@
if TSSLBase.SSL_VERSION != self._default_protocol:
warnings.warn(
'SSL_VERSION is deprecated.'
- 'please use ssl_version keyward argument instead.',
+ 'please use ssl_version keyword argument instead.',
DeprecationWarning, stacklevel=2)
self._context = ssl_opts.pop('ssl_context', None)
self._server_hostname = None
@@ -232,6 +232,7 @@
``validate_callback`` (cert, hostname) -> None:
Called after SSL handshake. Can raise when hostname does not
match the cert.
+ ``socket_keepalive`` enable TCP keepalive, default off.
"""
self.is_valid = False
self.peercert = None
@@ -259,9 +260,20 @@
kwargs['cert_reqs'] = ssl.CERT_REQUIRED if validate else ssl.CERT_NONE
unix_socket = kwargs.pop('unix_socket', None)
+ socket_keepalive = kwargs.pop('socket_keepalive', False)
self._validate_callback = kwargs.pop('validate_callback', _match_hostname)
TSSLBase.__init__(self, False, host, kwargs)
- TSocket.TSocket.__init__(self, host, port, unix_socket)
+ TSocket.TSocket.__init__(self, host, port, unix_socket,
+ socket_keepalive=socket_keepalive)
+
+ def close(self):
+ try:
+ self.handle.settimeout(0.001)
+ self.handle = self.handle.unwrap()
+ except (ssl.SSLError, socket.error, OSError):
+ # could not complete shutdown in a reasonable amount of time. bail.
+ pass
+ TSocket.TSocket.close(self)
@property
def validate(self):
diff --git a/lib/py/src/transport/TSocket.py b/lib/py/src/transport/TSocket.py
index a7d6617..c8be25a 100644
--- a/lib/py/src/transport/TSocket.py
+++ b/lib/py/src/transport/TSocket.py
@@ -50,7 +50,9 @@
class TSocket(TSocketBase):
"""Socket implementation of TTransport base."""
- def __init__(self, host='localhost', port=9090, unix_socket=None, socket_family=socket.AF_UNSPEC):
+ def __init__(self, host='localhost', port=9090, unix_socket=None,
+ socket_family=socket.AF_UNSPEC,
+ socket_keepalive=False):
"""Initialize a TSocket
@param host(str) The host to connect to.
@@ -58,6 +60,7 @@
@param unix_socket(str) The filename of a unix socket to connect to.
(host and port will be ignored.)
@param socket_family(int) The socket family to use with this socket.
+ @param socket_keepalive(bool) enable TCP keepalive, default off.
"""
self.host = host
self.port = port
@@ -65,6 +68,7 @@
self._unix_socket = unix_socket
self._timeout = None
self._socket_family = socket_family
+ self._socket_keepalive = socket_keepalive
def setHandle(self, h):
self.handle = h
@@ -99,6 +103,11 @@
raise TTransportException(TTransportException.NOT_OPEN, msg)
for family, socktype, _, _, sockaddr in addrs:
handle = self._do_open(family, socktype)
+
+ # TCP_KEEPALIVE
+ if self._socket_keepalive:
+ handle.setsockopt(socket.IPPROTO_TCP, socket.SO_KEEPALIVE, 1)
+
handle.settimeout(self._timeout)
try:
handle.connect(sockaddr)
diff --git a/lib/py/test/test_sslsocket.py b/lib/py/test/test_sslsocket.py
index f1344e5..598c174 100644
--- a/lib/py/test/test_sslsocket.py
+++ b/lib/py/test/test_sslsocket.py
@@ -213,6 +213,7 @@
return
fd, path = tempfile.mkstemp()
os.close(fd)
+ os.unlink(path)
try:
server = self._server_socket(unix_socket=path, keyfile=SERVER_KEY, certfile=SERVER_CERT)
self._assert_connection_success(server, path=path, cert_reqs=ssl.CERT_NONE)
diff --git a/lib/rb/Makefile.am b/lib/rb/Makefile.am
index 137edb4..1841065 100755
--- a/lib/rb/Makefile.am
+++ b/lib/rb/Makefile.am
@@ -31,6 +31,7 @@
clean-local:
$(BUNDLER) install
$(BUNDLER) exec rake clean
+ $(RM) -r spec/gen-rb/
check-local: all
$(BUNDLER) install
@@ -38,6 +39,9 @@
endif
+dist-hook:
+ $(RM) -r $(distdir)/spec/gen-rb/
+
EXTRA_DIST = \
coding_standards.md \
Rakefile \
diff --git a/lib/rb/Rakefile b/lib/rb/Rakefile
index cdecaa6..5e5e5ac 100644
--- a/lib/rb/Rakefile
+++ b/lib/rb/Rakefile
@@ -71,6 +71,7 @@
desc "Build the native library"
task :build_ext => :'gen-rb' do
+ next if defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/
Dir::chdir(File::dirname('ext/extconf.rb')) do
unless sh "ruby #{File::basename('ext/extconf.rb')}"
$stderr.puts "Failed to run extconf"
diff --git a/lib/rb/thrift.gemspec b/lib/rb/thrift.gemspec
index 3dd38ec..869e5d9 100644
--- a/lib/rb/thrift.gemspec
+++ b/lib/rb/thrift.gemspec
@@ -3,8 +3,8 @@
Gem::Specification.new do |s|
s.name = 'thrift'
- s.version = '0.12.1'
- s.authors = ['Thrift Developers']
+ s.version = '0.13.0'
+ s.authors = ['Apache Thrift Developers']
s.email = ['dev@thrift.apache.org']
s.homepage = 'http://thrift.apache.org'
s.summary = %q{Ruby bindings for Apache Thrift}
diff --git a/lib/rs/Cargo.toml b/lib/rs/Cargo.toml
index 44b35eb..bad2a38 100644
--- a/lib/rs/Cargo.toml
+++ b/lib/rs/Cargo.toml
@@ -1,19 +1,18 @@
[package]
name = "thrift"
description = "Rust bindings for the Apache Thrift RPC system"
-version = "0.12.1"
+version = "0.13.0"
license = "Apache-2.0"
authors = ["Apache Thrift Developers <dev@thrift.apache.org>"]
homepage = "http://thrift.apache.org"
documentation = "https://thrift.apache.org"
readme = "README.md"
-exclude = ["Makefile*", "test/**"]
+exclude = ["Makefile*", "test/**", "*.iml"]
keywords = ["thrift"]
[dependencies]
-byteorder = "~1.2.1"
-integer-encoding = "~1.0.4"
-log = "~0.3.8"
-threadpool = "~1.7.1"
-try_from = "~0.2.2"
-
+ordered-float = "0.5"
+byteorder = "1"
+integer-encoding = "1"
+log = "0.4"
+threadpool = "1.7"
diff --git a/lib/rs/README.md b/lib/rs/README.md
index f611a91..f518f4e 100644
--- a/lib/rs/README.md
+++ b/lib/rs/README.md
@@ -46,7 +46,16 @@
Breaking changes are minimized. When they are made they will be outlined below with transition guidelines.
-##### Thrift 0.12.x
+##### Thrift 0.13.0
+
+* **[THRIFT-4536]** - Use TryFrom from std, required rust 1.34.0 or higher
+
+ Previously TryFrom was from try_from crate, it is now from the std library,
+ but this functionality is only available in rust 1.34.0. Additionally,
+ ordered-float is now re-exported under the thrift module to reduce
+ possible dependency mismatches.
+
+##### Thrift 0.12.0
* **[THRIFT-4529]** - Rust enum variants are now camel-cased instead of uppercased to conform to Rust naming conventions
diff --git a/lib/rs/RELEASING.md b/lib/rs/RELEASING.md
new file mode 100644
index 0000000..073d7a0
--- /dev/null
+++ b/lib/rs/RELEASING.md
@@ -0,0 +1,57 @@
+# Publishing the thrift crate
+
+Publishing the Rust thrift crate is straightforward, and involves two major steps:
+
+1. Setting up your [crates.io](https://www.crates.io) account _(one-time)_
+
+2. Packaging/publishing the Rust thrift crate itself
+
+## Set up your crates.io account (one-time)
+
+1. Go to [crates.io](https://www.crates.io) and click the `Log In` button at the top right.
+
+ Log in **as the Github user with write permissions to the thrift repo!**
+
+2. Click your user icon button at the top right and select `Account Settings`.
+
+3. Click `New Token` next to `API Access`.
+
+ This generates a new API key that cargo uses to publish packages to crates.io.
+ Store this API key somewhere safe. If you will only use this Github account to
+ publish crates to crates.io you can follow the instructions to save the
+ generated key to `~/.cargo/credentials`.
+
+## Package and Publish
+
+You can use the automated script or run the release steps manually.
+
+**Important**: `cargo` expects that version numbers follow the semantic versioning format.
+This means that `THRIFT_RELEASE_VERSION` must have a major, minor and patch number, i.e., must
+be in the form `#.##.##`.
+
+#### Automated
+
+Run `./release.sh [THRIFT_RELEASE_VERSION]`.
+
+_Requires you to have stored your credentials in `~/.cargo/credentials`._
+
+#### Manual
+
+1. Edit `Cargo.toml` and update the `version = 1.0` key to `version = [THRIFT_RELEASE_VERSION]`
+
+2. `git add Cargo.toml`
+
+3. `git commit -m "Update thrift crate version to [THRIFT_RELEASE_VERSION]" -m "Client: rs"`
+
+4. `cargo login`
+
+ _(not required if you have stored your credentials in `~/.cargo/credentials`)_
+
+5. `cargo clean`
+
+6. `cargo package`
+
+ This step fails if there are any uncommitted or ignored files. Do **not** use the `--allow-dirty`
+ flag! Instead, add the highlighted files as entries in the `Cargo.toml` `exclude` key.
+
+7. `cargo publish`
diff --git a/lib/rs/release.sh b/lib/rs/release.sh
new file mode 100755
index 0000000..c4e5b48
--- /dev/null
+++ b/lib/rs/release.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+set -o errexit
+set -o pipefail
+set -o nounset
+
+if ! [[ $# -eq 1 && $1 =~ ^[0-9](\.[0-9][0-9]*){2}$ ]]; then
+ (>&2 echo "Usage: ./publish-crate.sh [THRIFT_RELEASE_VERSION] ")
+ (>&2 echo " THRIFT_RELEASE_VERSION is in semantic versioning format, i.e. #.##.##")
+ exit 1
+fi
+
+THRIFT_RELEASE_VERSION=${1:-}
+
+echo "Updating Cargo.toml to ${THRIFT_RELEASE_VERSION}"
+sed -i.old -e "s/^version = .*$/version = \"${THRIFT_RELEASE_VERSION}\"/g" Cargo.toml
+rm Cargo.toml.old
+
+echo "Committing updated Cargo.toml"
+git add Cargo.toml
+git commit -m "Update thrift crate version to ${THRIFT_RELEASE_VERSION}" -m "Client: rs"
+
+echo "Packaging and releasing rust thrift crate with version ${THRIFT_RELEASE_VERSION}"
+cargo clean
+cargo package
+cargo publish
diff --git a/lib/rs/src/errors.rs b/lib/rs/src/errors.rs
index 16a2576..6fb1aee 100644
--- a/lib/rs/src/errors.rs
+++ b/lib/rs/src/errors.rs
@@ -19,7 +19,7 @@
use std::error::Error as StdError;
use std::fmt::{Debug, Display, Formatter};
use std::{error, fmt, io, string};
-use try_from::TryFrom;
+use std::convert::TryFrom;
use protocol::{TFieldIdentifier, TInputProtocol, TOutputProtocol, TStructIdentifier, TType};
@@ -413,8 +413,8 @@
}
impl TryFrom<i32> for TransportErrorKind {
- type Err = Error;
- fn try_from(from: i32) -> Result<Self, Self::Err> {
+ type Error = Error;
+ fn try_from(from: i32) -> Result<Self, Self::Error> {
match from {
0 => Ok(TransportErrorKind::Unknown),
1 => Ok(TransportErrorKind::NotOpen),
@@ -543,8 +543,8 @@
}
impl TryFrom<i32> for ProtocolErrorKind {
- type Err = Error;
- fn try_from(from: i32) -> Result<Self, Self::Err> {
+ type Error = Error;
+ fn try_from(from: i32) -> Result<Self, Self::Error> {
match from {
0 => Ok(ProtocolErrorKind::Unknown),
1 => Ok(ProtocolErrorKind::InvalidData),
@@ -647,8 +647,8 @@
}
impl TryFrom<i32> for ApplicationErrorKind {
- type Err = Error;
- fn try_from(from: i32) -> Result<Self, Self::Err> {
+ type Error = Error;
+ fn try_from(from: i32) -> Result<Self, Self::Error> {
match from {
0 => Ok(ApplicationErrorKind::Unknown),
1 => Ok(ApplicationErrorKind::UnknownMethod),
diff --git a/lib/rs/src/lib.rs b/lib/rs/src/lib.rs
index ca5c7d6..a36ec99 100644
--- a/lib/rs/src/lib.rs
+++ b/lib/rs/src/lib.rs
@@ -49,9 +49,9 @@
#![doc(test(attr(allow(unused_variables), deny(warnings))))]
extern crate byteorder;
+extern crate ordered_float;
extern crate integer_encoding;
extern crate threadpool;
-extern crate try_from;
#[macro_use]
extern crate log;
@@ -85,3 +85,6 @@
/// As is convention this is a typedef of `std::result::Result`
/// with `E` defined as the `thrift::Error` type.
pub type Result<T> = std::result::Result<T, self::Error>;
+
+// Re-export ordered-float, since it is used by the generator
+pub use ordered_float::OrderedFloat as OrderedFloat;
\ No newline at end of file
diff --git a/lib/rs/src/protocol/binary.rs b/lib/rs/src/protocol/binary.rs
index 19aff3d..0920fc4 100644
--- a/lib/rs/src/protocol/binary.rs
+++ b/lib/rs/src/protocol/binary.rs
@@ -16,8 +16,7 @@
// under the License.
use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
-use std::convert::From;
-use try_from::TryFrom;
+use std::convert::{From, TryFrom};
use super::{
TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier, TMapIdentifier,
diff --git a/lib/rs/src/protocol/compact.rs b/lib/rs/src/protocol/compact.rs
index df5edaa..334e820 100644
--- a/lib/rs/src/protocol/compact.rs
+++ b/lib/rs/src/protocol/compact.rs
@@ -17,9 +17,8 @@
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use integer_encoding::{VarIntReader, VarIntWriter};
-use std::convert::From;
+use std::convert::{From, TryFrom};
use std::io;
-use try_from::TryFrom;
use super::{
TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier, TMapIdentifier,
diff --git a/lib/rs/src/protocol/mod.rs b/lib/rs/src/protocol/mod.rs
index 11c0289..1ab1658 100644
--- a/lib/rs/src/protocol/mod.rs
+++ b/lib/rs/src/protocol/mod.rs
@@ -57,10 +57,9 @@
//! protocol.write_field_end().unwrap();
//! ```
-use std::convert::From;
+use std::convert::{From, TryFrom};
use std::fmt;
use std::fmt::{Display, Formatter};
-use try_from::TryFrom;
use transport::{TReadTransport, TWriteTransport};
use {ProtocolError, ProtocolErrorKind};
@@ -770,8 +769,8 @@
}
impl TryFrom<u8> for TMessageType {
- type Err = ::Error;
- fn try_from(b: u8) -> ::Result<Self> {
+ type Error = ::Error;
+ fn try_from(b: u8) -> Result<Self, Self::Error> {
match b {
0x01 => Ok(TMessageType::Call),
0x02 => Ok(TMessageType::Reply),
diff --git a/lib/rs/test/src/lib.rs b/lib/rs/test/src/lib.rs
index e5e176e..9debdca 100644
--- a/lib/rs/test/src/lib.rs
+++ b/lib/rs/test/src/lib.rs
@@ -15,9 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-extern crate ordered_float;
extern crate thrift;
-extern crate try_from;
pub mod base_one;
pub mod base_two;
diff --git a/lib/st/package.xml b/lib/st/package.xml
index 8ebbd6d..21b7adc 100644
--- a/lib/st/package.xml
+++ b/lib/st/package.xml
@@ -17,7 +17,7 @@
specific language governing permissions and limitations
under the License.
-->
-<!-- Apache Thrift Smalltalk library version 0.12.1 -->
+<!-- Apache Thrift Smalltalk library version 0.13.0 -->
<package>
<name>libthrift-st</name>
<file>thrift.st</file>
diff --git a/compiler/cpp/test/cpp_plugin_test.sh b/lib/swift/Makefile.am
old mode 100755
new mode 100644
similarity index 71%
copy from compiler/cpp/test/cpp_plugin_test.sh
copy to lib/swift/Makefile.am
index ddb2e0a..6b88b06
--- a/compiler/cpp/test/cpp_plugin_test.sh
+++ b/lib/swift/Makefile.am
@@ -1,5 +1,3 @@
-#!/bin/sh
-
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -19,9 +17,30 @@
# under the License.
#
-# this file is intended to be invoked by make.
-set -e
-mkdir -p gen-cpp gen-mycpp
-PATH=.:"$PATH" ../thrift -r -out gen-cpp -gen cpp ../../../test/Include.thrift
-PATH=.:"$PATH" ../thrift -r -out gen-mycpp -gen mycpp ../../../test/Include.thrift
-diff -urN gen-cpp gen-mycpp
+SUBDIRS = .
+
+all-local:
+ swift build --configuration release
+
+install-exec-hook:
+ swift install
+
+clean-local:
+ swift package clean
+ rm -rf .build
+
+precross:
+ swift
+
+check-local:
+ swift test
+
+EXTRA_DIST = \
+ Package.swift \
+ Sources \
+ Tests \
+ README.md
+
+MAINTAINERCLEANFILES = \
+ Makefile \
+ Makefile.in
diff --git a/lib/swift/README.md b/lib/swift/README.md
index 4fdeacf..6f10961 100644
--- a/lib/swift/README.md
+++ b/lib/swift/README.md
@@ -22,7 +22,6 @@
## Build
-
swift build
## Test
diff --git a/lib/swift/Sources/Thrift.swift b/lib/swift/Sources/Thrift.swift
index 5bd1758..45c68f2 100644
--- a/lib/swift/Sources/Thrift.swift
+++ b/lib/swift/Sources/Thrift.swift
@@ -1,3 +1,3 @@
class Thrift {
- let version = "1.1.0"
+ let version = "0.13.0"
}
diff --git a/lib/swift/Tests/ThriftTests/ThriftTests.swift b/lib/swift/Tests/ThriftTests/ThriftTests.swift
index 9316100..ae47f38 100644
--- a/lib/swift/Tests/ThriftTests/ThriftTests.swift
+++ b/lib/swift/Tests/ThriftTests/ThriftTests.swift
@@ -3,7 +3,7 @@
class ThriftTests: XCTestCase {
func testVersion() {
- XCTAssertEqual(Thrift().version, "1.1.0")
+ XCTAssertEqual(Thrift().version, "0.13.0")
}
func test_in_addr_extension() {
diff --git a/lib/ts/.gitignore b/lib/ts/.gitignore
new file mode 100644
index 0000000..24f250e
--- /dev/null
+++ b/lib/ts/.gitignore
@@ -0,0 +1,2 @@
+test/build/
+test/gen-*
diff --git a/lib/ts/Gruntfile.js b/lib/ts/Gruntfile.js
new file mode 100644
index 0000000..fcd79f8
--- /dev/null
+++ b/lib/ts/Gruntfile.js
@@ -0,0 +1,163 @@
+//To build dist/thrift.js, dist/thrift.min.js and doc/*
+//run grunt at the command line in this directory.
+//Prerequisites:
+// Node Setup - nodejs.org
+// Grunt Setup - npm install //reads the ./package.json and installs project dependencies
+// Run grunt - npx grunt // uses project-local installed version of grunt (from package.json)
+
+module.exports = function(grunt) {
+ 'use strict';
+
+ grunt.initConfig({
+ pkg: grunt.file.readJSON('package.json'),
+ concat: {
+ options: {
+ separator: ';'
+ },
+ dist: {
+ src: ['src/**/*.js'],
+ dest: 'dist/<%= pkg.name %>.js'
+ }
+ },
+ shell: {
+ InstallThriftJS: {
+ command: 'mkdir -p test/build/ts/lib; cp ../js/src/thrift.js test/build/ts/thrift.js'
+ },
+ InstallThriftNodeJSDep: {
+ command: 'cd ../..; npm install'
+ },
+ InstallTestLibs: {
+ command: 'cd test; ant download_jslibs'
+ },
+ ThriftGen: {
+ command: [
+ 'mkdir -p test/gen-js',
+ '../../compiler/cpp/thrift -gen js:ts --out test/gen-js ../../test/ThriftTest.thrift',
+ 'mkdir -p test/gen-nodejs',
+ '../../compiler/cpp/thrift -gen js:node,ts --out test/gen-nodejs ../../test/ThriftTest.thrift',
+ ].join(' && ')
+ },
+ ThriftBrowserifyNodeInt64: {
+ command: [
+ './node_modules/browserify/bin/cmd.js ./node_modules/node-int64/Int64.js -s Int64 -o test/build/js/lib/Int64.js',
+ './node_modules/browserify/bin/cmd.js ../nodejs/lib/thrift/int64_util.js -s Int64Util -o test/build/js/lib/Int64Util.js',
+ './node_modules/browserify/bin/cmd.js ./node_modules/json-int64/index.js -s JSONInt64 -o test/build/js/lib/JSONInt64.js'
+ ].join(' && ')
+ },
+ ThriftGenInt64: {
+ command: '../../compiler/cpp/thrift -gen js:ts -o test ../../test/Int64Test.thrift'
+ },
+ ThriftTestServer: {
+ options: {
+ async: true,
+ execOptions: {
+ cwd: "./test",
+ env: {NODE_PATH: "../../nodejs/lib:../../../node_modules"}
+ }
+ },
+ command: "node server_http.js",
+ },
+ BuildTS: {
+ options: {
+ execOptions: {
+ cwd: "./test",
+ }
+ },
+ command : "../node_modules/typescript/bin/tsc --listFiles --outDir build/ts"
+ },
+ BrowserifyCompiledTS: {
+ command: [
+ "./node_modules/browserify/bin/cmd.js test/build/ts/test.js -o test/build/ts/lib/test.js --standalone test",
+ "./node_modules/browserify/bin/cmd.js test/build/ts/test-int64.js -o test/build/ts/lib/test-int64.js --standalone testInt64",
+ ].join(" && ")
+ },
+ InstallGeneratedCode: {
+ command: [
+ "mkdir -p test/build/ts",
+ "cp -r test/gen-js test/build/ts"
+ ].join(" && ")
+ },
+ },
+ qunit: {
+ ThriftJS: {
+ options: {
+ urls: [
+ 'http://localhost:8089/test.html'
+ ],
+ puppeteer: {
+ headless: true,
+ args: ['--no-sandbox'],
+ },
+ }
+ },
+ ThriftJS_Int64: {
+ options: {
+ urls: [
+ 'http://localhost:8089/test-int64.html'
+ ],
+ puppeteer: {
+ headless: true,
+ args: ['--no-sandbox'],
+ ignoreHTTPSErrors: true,
+ },
+ }
+ },
+ },
+ jshint: {
+ // The main Thrift library file. not es6 yet :(
+ lib: {
+ src: ['../js/src/**/*.js'],
+ },
+ // The test files use es6
+ test: {
+ src: ['Gruntfile.js', 'test/*.js'],
+ options: {
+ esversion: 6,
+ }
+ },
+ gen_js_code: {
+ src: ['test/gen-js/*.js'],
+ },
+ gen_node_code: {
+ src: ['test/gen-nodejs/*.js'],
+ options: {
+ node: true,
+ }
+ },
+ },
+ });
+
+ grunt.loadNpmTasks('grunt-contrib-jshint');
+ grunt.loadNpmTasks('grunt-contrib-qunit');
+ grunt.loadNpmTasks('grunt-shell-spawn');
+
+ grunt.registerTask('wait', 'Wait just one second for the server to start', function () {
+ var done = this.async();
+ setTimeout(function() {
+ done(true);
+ }, 1000);
+ });
+
+ grunt.registerTask('installAndGenerate', [
+ 'shell:InstallThriftJS',
+ 'shell:InstallThriftNodeJSDep',
+ 'shell:ThriftGen',
+ 'shell:ThriftBrowserifyNodeInt64',
+ 'shell:ThriftGenInt64',
+ 'shell:InstallTestLibs',
+ 'shell:BuildTS',
+ 'shell:InstallGeneratedCode',
+ 'shell:BrowserifyCompiledTS',
+ ]);
+
+ grunt.registerTask('test', [
+ 'installAndGenerate',
+ 'jshint',
+ 'shell:ThriftTestServer',
+ 'wait',
+ 'qunit:ThriftJS',
+ 'qunit:ThriftJS_Int64',
+ 'shell:ThriftTestServer:kill',
+ ]);
+ grunt.registerTask('default', ['test']);
+};
diff --git a/lib/ts/Makefile.am b/lib/ts/Makefile.am
new file mode 100644
index 0000000..62ea206
--- /dev/null
+++ b/lib/ts/Makefile.am
@@ -0,0 +1,58 @@
+#
+# 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.
+#
+
+# Make sure this doesn't fail if ant is not configured.
+# We call install twice to work around npm issues
+#
+if HAVE_NPM
+
+prereq:
+ $(NPM) install || $(NPM) install
+ $(NPM) list
+
+check-local: prereq all
+ ./node_modules/.bin/grunt
+
+doc: prereq
+ ./node_modules/.bin/grunt jsdoc
+
+endif
+
+clean-local:
+ $(RM) -r dist
+ $(RM) -r doc
+ $(RM) -r node_modules
+ $(RM) -r test/build/
+ $(RM) -r test/gen-*/
+
+dist-hook:
+ $(RM) -r $(distdir)/dist/
+ $(RM) -r $(distdir)/doc/
+ $(RM) -r $(distdir)/node_modules/
+ $(RM) -r $(distdir)/test/build/
+ $(RM) -r $(distdir)/test/gen-*/
+
+EXTRA_DIST = \
+ coding_standards.md \
+ Gruntfile.js \
+ package.json \
+ package-lock.json \
+ thrift.d.ts \
+ tsconfig.json
+
diff --git a/lib/ts/dist/thrift.js b/lib/ts/dist/thrift.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/ts/dist/thrift.js
diff --git a/lib/ts/dist/thrift.min.js b/lib/ts/dist/thrift.min.js
new file mode 100644
index 0000000..8e14f2d
--- /dev/null
+++ b/lib/ts/dist/thrift.min.js
@@ -0,0 +1 @@
+/*! thrift 07-01-2019 */
diff --git a/lib/ts/package-lock.json b/lib/ts/package-lock.json
new file mode 100644
index 0000000..8d0a7ff
--- /dev/null
+++ b/lib/ts/package-lock.json
@@ -0,0 +1,4955 @@
+{
+ "name": "thrift",
+ "version": "0.13.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@types/node": {
+ "version": "10.12.18",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz",
+ "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==",
+ "dev": true
+ },
+ "@types/node-int64": {
+ "version": "0.4.29",
+ "resolved": "https://registry.npmjs.org/@types/node-int64/-/node-int64-0.4.29.tgz",
+ "integrity": "sha512-rHXvenLTj/CcsmNAebaBOhxQ2MqEGl3yXZZcZ21XYR+gzGTTcpOy2N4IxpvTCz48loyQNatHvfn6GhIbbZ1R3Q==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/phantom": {
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/@types/phantom/-/phantom-3.2.5.tgz",
+ "integrity": "sha512-7m36DoKSvZgBGWp0xiJ74eHnuotyrpDyQ6m+lers5iMvW4QX+RvBENn7PCjNix7OVqPWlBM+7AqzYVIQ7NrKrA==",
+ "dev": true
+ },
+ "@types/qunit": {
+ "version": "2.5.4",
+ "resolved": "https://registry.npmjs.org/@types/qunit/-/qunit-2.5.4.tgz",
+ "integrity": "sha512-VHi2lEd4/zp8OOouf43JXGJJ5ZxHvdLL1dU0Yakp6Iy73SjpuXl7yjwAwmh1qhTv8krDgHteSwaySr++uXX9YQ==",
+ "dev": true
+ },
+ "JSONStream": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+ "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+ "dev": true,
+ "requires": {
+ "jsonparse": "^1.2.0",
+ "through": ">=2.2.7 <3"
+ }
+ },
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+ },
+ "acorn": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz",
+ "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==",
+ "dev": true
+ },
+ "acorn-dynamic-import": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz",
+ "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==",
+ "dev": true
+ },
+ "acorn-node": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz",
+ "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==",
+ "dev": true,
+ "requires": {
+ "acorn": "^6.0.2",
+ "acorn-dynamic-import": "^4.0.0",
+ "acorn-walk": "^6.1.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "acorn-walk": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz",
+ "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==",
+ "dev": true
+ },
+ "agent-base": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
+ "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
+ "dev": true,
+ "requires": {
+ "es6-promisify": "^5.0.0"
+ }
+ },
+ "ajv": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz",
+ "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "align-text": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2",
+ "longest": "^1.0.1",
+ "repeat-string": "^1.5.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ },
+ "dependencies": {
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ }
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
+ "array-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
+ "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
+ "dev": true
+ },
+ "array-filter": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
+ "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
+ "dev": true
+ },
+ "array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+ "dev": true
+ },
+ "array-map": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
+ "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=",
+ "dev": true
+ },
+ "array-reduce": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz",
+ "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=",
+ "dev": true
+ },
+ "array-slice": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "asn1.js": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "assert": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+ "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+ "dev": true,
+ "requires": {
+ "util": "0.10.3"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+ "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+ "dev": true
+ },
+ "util": {
+ "version": "0.10.3",
+ "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.1"
+ }
+ }
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true
+ },
+ "async": {
+ "version": "1.5.2",
+ "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+ "dev": true
+ },
+ "async-limiter": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
+ "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
+ "dev": true
+ },
+ "babylon": {
+ "version": "7.0.0-beta.19",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.19.tgz",
+ "integrity": "sha512-Vg0C9s/REX6/WIXN37UKpv5ZhRi6A4pjHlpkE34+8/a6c2W1Q692n3hmc+SZG5lKRnaExLUbxtJ1SVT+KaCQ/A=="
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "requires": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "base64-js": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
+ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "dev": true,
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "bluebird": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz",
+ "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw=="
+ },
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+ "dev": true
+ },
+ "browser-pack": {
+ "version": "6.1.0",
+ "resolved": "http://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz",
+ "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "combine-source-map": "~0.8.0",
+ "defined": "^1.0.0",
+ "safe-buffer": "^5.1.1",
+ "through2": "^2.0.0",
+ "umd": "^3.0.0"
+ }
+ },
+ "browser-resolve": {
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz",
+ "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==",
+ "dev": true,
+ "requires": {
+ "resolve": "1.1.7"
+ },
+ "dependencies": {
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ }
+ }
+ },
+ "browserify": {
+ "version": "16.2.3",
+ "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz",
+ "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "assert": "^1.4.0",
+ "browser-pack": "^6.0.1",
+ "browser-resolve": "^1.11.0",
+ "browserify-zlib": "~0.2.0",
+ "buffer": "^5.0.2",
+ "cached-path-relative": "^1.0.0",
+ "concat-stream": "^1.6.0",
+ "console-browserify": "^1.1.0",
+ "constants-browserify": "~1.0.0",
+ "crypto-browserify": "^3.0.0",
+ "defined": "^1.0.0",
+ "deps-sort": "^2.0.0",
+ "domain-browser": "^1.2.0",
+ "duplexer2": "~0.1.2",
+ "events": "^2.0.0",
+ "glob": "^7.1.0",
+ "has": "^1.0.0",
+ "htmlescape": "^1.1.0",
+ "https-browserify": "^1.0.0",
+ "inherits": "~2.0.1",
+ "insert-module-globals": "^7.0.0",
+ "labeled-stream-splicer": "^2.0.0",
+ "mkdirp": "^0.5.0",
+ "module-deps": "^6.0.0",
+ "os-browserify": "~0.3.0",
+ "parents": "^1.0.1",
+ "path-browserify": "~0.0.0",
+ "process": "~0.11.0",
+ "punycode": "^1.3.2",
+ "querystring-es3": "~0.2.0",
+ "read-only-stream": "^2.0.0",
+ "readable-stream": "^2.0.2",
+ "resolve": "^1.1.4",
+ "shasum": "^1.0.0",
+ "shell-quote": "^1.6.1",
+ "stream-browserify": "^2.0.0",
+ "stream-http": "^2.0.0",
+ "string_decoder": "^1.1.1",
+ "subarg": "^1.0.0",
+ "syntax-error": "^1.1.1",
+ "through2": "^2.0.0",
+ "timers-browserify": "^1.0.1",
+ "tty-browserify": "0.0.1",
+ "url": "~0.11.0",
+ "util": "~0.10.1",
+ "vm-browserify": "^1.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "browserify-aes": {
+ "version": "1.2.0",
+ "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+ "dev": true,
+ "requires": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "browserify-cipher": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+ "dev": true,
+ "requires": {
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
+ }
+ },
+ "browserify-des": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+ "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "browserify-rsa": {
+ "version": "4.0.1",
+ "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "randombytes": "^2.0.1"
+ }
+ },
+ "browserify-sign": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
+ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.1",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.2",
+ "elliptic": "^6.0.0",
+ "inherits": "^2.0.1",
+ "parse-asn1": "^5.0.0"
+ }
+ },
+ "browserify-zlib": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+ "dev": true,
+ "requires": {
+ "pako": "~1.0.5"
+ }
+ },
+ "buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+ "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "dev": true
+ },
+ "buffer-shims": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
+ "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=",
+ "dev": true
+ },
+ "buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+ "dev": true
+ },
+ "bufferutil": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz",
+ "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==",
+ "requires": {
+ "node-gyp-build": "~3.7.0"
+ }
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+ "dev": true
+ },
+ "builtin-status-codes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+ "dev": true
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ }
+ },
+ "cached-path-relative": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz",
+ "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "2.1.0",
+ "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^2.0.0",
+ "map-obj": "^1.0.0"
+ }
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+ "dev": true
+ },
+ "catharsis": {
+ "version": "0.8.9",
+ "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.9.tgz",
+ "integrity": "sha1-mMyJDKZS3S7w5ws3klMQ/56Q/Is=",
+ "requires": {
+ "underscore-contrib": "~0.3.0"
+ }
+ },
+ "center-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+ "dev": true,
+ "requires": {
+ "align-text": "^0.1.3",
+ "lazy-cache": "^1.0.3"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "cli": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
+ "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=",
+ "dev": true,
+ "requires": {
+ "exit": "0.1.2",
+ "glob": "^7.1.1"
+ }
+ },
+ "cliui": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+ "dev": true,
+ "requires": {
+ "center-align": "^0.1.1",
+ "right-align": "^0.1.1",
+ "wordwrap": "0.0.2"
+ }
+ },
+ "coffeescript": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz",
+ "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=",
+ "dev": true
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "requires": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ }
+ },
+ "color": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz",
+ "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.1",
+ "color-string": "^1.5.2"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "color-string": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
+ "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
+ "dev": true,
+ "requires": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
+ "colornames": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz",
+ "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=",
+ "dev": true
+ },
+ "colors": {
+ "version": "1.1.2",
+ "resolved": "http://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+ "dev": true
+ },
+ "colorspace": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.1.tgz",
+ "integrity": "sha512-pI3btWyiuz7Ken0BWh9Elzsmv2bM9AhA7psXib4anUXy/orfZ/E0MbQwhSOG/9L8hLlalqrU0UhOuqxW1YjmVw==",
+ "dev": true,
+ "requires": {
+ "color": "3.0.x",
+ "text-hex": "1.0.x"
+ }
+ },
+ "combine-source-map": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz",
+ "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=",
+ "dev": true,
+ "requires": {
+ "convert-source-map": "~1.1.0",
+ "inline-source-map": "~0.6.0",
+ "lodash.memoize": "~3.0.3",
+ "source-map": "~0.5.3"
+ }
+ },
+ "combined-stream": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
+ "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "console-browserify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+ "dev": true,
+ "requires": {
+ "date-now": "^0.1.4"
+ }
+ },
+ "constants-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.1.3",
+ "resolved": "http://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz",
+ "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=",
+ "dev": true
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "create-ecdh": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
+ "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.0.0"
+ }
+ },
+ "create-hash": {
+ "version": "1.2.0",
+ "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.7",
+ "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "crypto-browserify": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+ "dev": true,
+ "requires": {
+ "browserify-cipher": "^1.0.0",
+ "browserify-sign": "^4.0.0",
+ "create-ecdh": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.0",
+ "diffie-hellman": "^5.0.0",
+ "inherits": "^2.0.1",
+ "pbkdf2": "^3.0.3",
+ "public-encrypt": "^4.0.0",
+ "randombytes": "^2.0.0",
+ "randomfill": "^1.0.3"
+ }
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+ "dev": true,
+ "requires": {
+ "array-find-index": "^1.0.1"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "date-now": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
+ "dev": true
+ },
+ "dateformat": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
+ "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^4.0.1",
+ "meow": "^3.3.0"
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "dev": true
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "dependencies": {
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "defined": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
+ "dev": true
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "deps-sort": {
+ "version": "2.0.0",
+ "resolved": "http://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz",
+ "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "shasum": "^1.0.0",
+ "subarg": "^1.0.0",
+ "through2": "^2.0.0"
+ }
+ },
+ "des.js": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
+ "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "detect-file": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+ "dev": true
+ },
+ "detective": {
+ "version": "5.1.0",
+ "resolved": "http://registry.npmjs.org/detective/-/detective-5.1.0.tgz",
+ "integrity": "sha512-TFHMqfOvxlgrfVzTEkNBSh9SvSNX/HfF4OFI2QFGCyPm02EsyILqnUeb5P6q7JZ3SFNTBL5t2sePRgrN4epUWQ==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.3.0",
+ "defined": "^1.0.0",
+ "minimist": "^1.1.1"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
+ "diagnostics": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz",
+ "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==",
+ "dev": true,
+ "requires": {
+ "colorspace": "1.1.x",
+ "enabled": "1.0.x",
+ "kuler": "1.0.x"
+ }
+ },
+ "diffie-hellman": {
+ "version": "5.0.3",
+ "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
+ }
+ },
+ "dom-serializer": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
+ "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "~1.1.1",
+ "entities": "~1.1.1"
+ },
+ "dependencies": {
+ "domelementtype": {
+ "version": "1.1.3",
+ "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+ "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
+ "dev": true
+ },
+ "entities": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+ "dev": true
+ }
+ }
+ },
+ "domain-browser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+ "dev": true
+ },
+ "domelementtype": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+ "dev": true
+ },
+ "domhandler": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+ "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "domutils": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+ "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
+ "duplexer2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "dev": true,
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "elliptic": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz",
+ "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.4.0",
+ "brorand": "^1.0.1",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.0"
+ }
+ },
+ "enabled": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz",
+ "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=",
+ "dev": true,
+ "requires": {
+ "env-variable": "0.0.x"
+ }
+ },
+ "entities": {
+ "version": "1.0.0",
+ "resolved": "http://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+ "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=",
+ "dev": true
+ },
+ "env-variable": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz",
+ "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==",
+ "dev": true
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es6-promise": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz",
+ "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==",
+ "dev": true
+ },
+ "es6-promisify": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+ "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "^4.0.3"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "dev": true
+ },
+ "eventemitter2": {
+ "version": "0.4.14",
+ "resolved": "http://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+ "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
+ "dev": true
+ },
+ "events": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz",
+ "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==",
+ "dev": true
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "dev": true,
+ "requires": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+ "dev": true
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "extract-zip": {
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
+ "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
+ "dev": true,
+ "requires": {
+ "concat-stream": "1.6.2",
+ "debug": "2.6.9",
+ "mkdirp": "0.5.1",
+ "yauzl": "2.4.1"
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "dev": true
+ },
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+ "dev": true
+ },
+ "fast-safe-stringify": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz",
+ "integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==",
+ "dev": true
+ },
+ "fd-slicer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+ "dev": true,
+ "requires": {
+ "pend": "~1.2.0"
+ }
+ },
+ "fecha": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
+ "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==",
+ "dev": true
+ },
+ "figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5",
+ "object-assign": "^4.1.0"
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "dev": true,
+ "requires": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "findup-sync": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
+ "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
+ "dev": true,
+ "requires": {
+ "glob": "~5.0.0"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+ "dev": true,
+ "requires": {
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ }
+ }
+ },
+ "fined": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.1.tgz",
+ "integrity": "sha512-jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g==",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "is-plain-object": "^2.0.3",
+ "object.defaults": "^1.1.0",
+ "object.pick": "^1.2.0",
+ "parse-filepath": "^1.0.1"
+ }
+ },
+ "flagged-respawn": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
+ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
+ "dev": true
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true
+ },
+ "for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.1"
+ }
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "requires": {
+ "map-cache": "^0.2.2"
+ }
+ },
+ "fs-extra": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+ "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0"
+ },
+ "dependencies": {
+ "klaw": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.9"
+ }
+ }
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "get-assigned-identifiers": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
+ "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+ "dev": true
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true
+ },
+ "getobject": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz",
+ "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "global-modules": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "dev": true,
+ "requires": {
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
+ }
+ },
+ "global-prefix": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "is-windows": "^1.0.1",
+ "which": "^1.2.14"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.15",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
+ },
+ "grunt": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.3.tgz",
+ "integrity": "sha512-/JzmZNPfKorlCrrmxWqQO4JVodO+DVd5XX4DkocL/1WlLlKVLE9+SdEIempOAxDhWPysLle6afvn/hg7Ck2k9g==",
+ "dev": true,
+ "requires": {
+ "coffeescript": "~1.10.0",
+ "dateformat": "~1.0.12",
+ "eventemitter2": "~0.4.13",
+ "exit": "~0.1.1",
+ "findup-sync": "~0.3.0",
+ "glob": "~7.0.0",
+ "grunt-cli": "~1.2.0",
+ "grunt-known-options": "~1.1.0",
+ "grunt-legacy-log": "~2.0.0",
+ "grunt-legacy-util": "~1.1.1",
+ "iconv-lite": "~0.4.13",
+ "js-yaml": "~3.5.2",
+ "minimatch": "~3.0.2",
+ "mkdirp": "~0.5.1",
+ "nopt": "~3.0.6",
+ "path-is-absolute": "~1.0.0",
+ "rimraf": "~2.6.2"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
+ "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.2",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "grunt-cli": {
+ "version": "1.2.0",
+ "resolved": "http://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
+ "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=",
+ "dev": true,
+ "requires": {
+ "findup-sync": "~0.3.0",
+ "grunt-known-options": "~1.1.0",
+ "nopt": "~3.0.6",
+ "resolve": "~1.1.0"
+ }
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-cli": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz",
+ "integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==",
+ "dev": true,
+ "requires": {
+ "grunt-known-options": "~1.1.0",
+ "interpret": "~1.1.0",
+ "liftoff": "~2.5.0",
+ "nopt": "~4.0.1",
+ "v8flags": "~3.1.1"
+ }
+ },
+ "grunt-contrib-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-1.0.1.tgz",
+ "integrity": "sha1-YVCYYwhOhx1+ht5IwBUlntl3Rb0=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.0.0",
+ "source-map": "^0.5.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-jshint": {
+ "version": "1.1.0",
+ "resolved": "http://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-1.1.0.tgz",
+ "integrity": "sha1-Np2QmyWTxA6L55lAshNAhQx5Oaw=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.1",
+ "hooker": "^0.2.3",
+ "jshint": "~2.9.4"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-qunit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-3.1.0.tgz",
+ "integrity": "sha512-mdk8UltH6mxCD63E0hTXMAts42DOi4z4bBBrY7qnuHiShflMF7IueSMYe0zWaZ2dO8mgujh57Zfny2EbigJhRg==",
+ "dev": true,
+ "requires": {
+ "eventemitter2": "^5.0.1",
+ "p-each-series": "^1.0.0",
+ "puppeteer": "^1.11.0"
+ },
+ "dependencies": {
+ "eventemitter2": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz",
+ "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-contrib-uglify": {
+ "version": "1.0.2",
+ "resolved": "http://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-1.0.2.tgz",
+ "integrity": "sha1-rmekb5FT7dTLEYE6Vetpxw19svs=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.0.0",
+ "lodash": "^4.0.1",
+ "maxmin": "^1.1.0",
+ "uglify-js": "~2.6.2",
+ "uri-path": "^1.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-jsdoc": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/grunt-jsdoc/-/grunt-jsdoc-2.3.0.tgz",
+ "integrity": "sha512-gC66TCRXeQMj3HIyqVSBJm8zdUz43e5vaG/PLO/627A1edbJnzxhJV7nF0KqLwMM0RDNu1istC6fvfnYqFKi3w==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^6.0.5",
+ "jsdoc": "~3.5.5",
+ "marked": "^0.5.0"
+ },
+ "dependencies": {
+ "marked": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.5.2.tgz",
+ "integrity": "sha512-fdZvBa7/vSQIZCi4uuwo2N3q+7jJURpMVCcbaX0S1Mg65WZ5ilXvC67MviJAsdjqqgD+CEq4RKo5AYGgINkVAA==",
+ "dev": true
+ }
+ }
+ },
+ "grunt-known-options": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz",
+ "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==",
+ "dev": true
+ },
+ "grunt-legacy-log": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz",
+ "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==",
+ "dev": true,
+ "requires": {
+ "colors": "~1.1.2",
+ "grunt-legacy-log-utils": "~2.0.0",
+ "hooker": "~0.2.3",
+ "lodash": "~4.17.5"
+ }
+ },
+ "grunt-legacy-log-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz",
+ "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==",
+ "dev": true,
+ "requires": {
+ "chalk": "~2.4.1",
+ "lodash": "~4.17.10"
+ }
+ },
+ "grunt-legacy-util": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz",
+ "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==",
+ "dev": true,
+ "requires": {
+ "async": "~1.5.2",
+ "exit": "~0.1.1",
+ "getobject": "~0.1.0",
+ "hooker": "~0.2.3",
+ "lodash": "~4.17.10",
+ "underscore.string": "~3.3.4",
+ "which": "~1.3.0"
+ }
+ },
+ "grunt-shell-spawn": {
+ "version": "0.3.12",
+ "resolved": "https://registry.npmjs.org/grunt-shell-spawn/-/grunt-shell-spawn-0.3.12.tgz",
+ "integrity": "sha512-TprZct92sQ4M2Q92piaeLsCrx4+gq/ageuxjZsRG6cglKt7x7rGA3YHt8D30+G789v+/pw4l0tDjEyrkMXx2tA==",
+ "dev": true,
+ "requires": {
+ "grunt": ">=0.4.x"
+ }
+ },
+ "gzip-size": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-1.0.0.tgz",
+ "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=",
+ "dev": true,
+ "requires": {
+ "browserify-zlib": "^0.1.4",
+ "concat-stream": "^1.4.1"
+ },
+ "dependencies": {
+ "browserify-zlib": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
+ "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
+ "dev": true,
+ "requires": {
+ "pako": "~0.2.0"
+ }
+ },
+ "pako": {
+ "version": "0.2.9",
+ "resolved": "http://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+ "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
+ "dev": true
+ }
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.5.5",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "hash-base": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "hash.js": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+ "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "hasha": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
+ "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=",
+ "dev": true,
+ "requires": {
+ "is-stream": "^1.0.1",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "dev": true,
+ "requires": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "homedir-polyfill": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
+ "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
+ "dev": true,
+ "requires": {
+ "parse-passwd": "^1.0.0"
+ }
+ },
+ "hooker": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
+ "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+ "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
+ "dev": true
+ },
+ "htmlescape": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz",
+ "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=",
+ "dev": true
+ },
+ "htmlparser2": {
+ "version": "3.8.3",
+ "resolved": "http://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
+ "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1",
+ "domhandler": "2.3",
+ "domutils": "1.5",
+ "entities": "1.0",
+ "readable-stream": "1.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "https-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+ "dev": true
+ },
+ "https-proxy-agent": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
+ "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
+ "dev": true,
+ "requires": {
+ "agent-base": "^4.1.0",
+ "debug": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ }
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ieee754": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz",
+ "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+ "dev": true,
+ "requires": {
+ "repeating": "^2.0.0"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+ "dev": true
+ },
+ "inline-source-map": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz",
+ "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=",
+ "dev": true,
+ "requires": {
+ "source-map": "~0.5.3"
+ }
+ },
+ "insert-module-globals": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz",
+ "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "acorn-node": "^1.5.2",
+ "combine-source-map": "^0.8.0",
+ "concat-stream": "^1.6.1",
+ "is-buffer": "^1.1.0",
+ "path-is-absolute": "^1.0.1",
+ "process": "~0.11.0",
+ "through2": "^2.0.0",
+ "undeclared-identifiers": "^1.1.2",
+ "xtend": "^4.0.0"
+ }
+ },
+ "interpret": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
+ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
+ "dev": true
+ },
+ "is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+ "dev": true,
+ "requires": {
+ "is-relative": "^1.0.0",
+ "is-windows": "^1.0.1"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "is-builtin-module": {
+ "version": "1.0.0",
+ "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+ "dev": true,
+ "requires": {
+ "builtin-modules": "^1.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-finite": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "is-relative": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+ "dev": true,
+ "requires": {
+ "is-unc-path": "^1.0.0"
+ }
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "is-unc-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+ "dev": true,
+ "requires": {
+ "unc-path-regex": "^0.1.2"
+ }
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.5.5",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz",
+ "integrity": "sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.2",
+ "esprima": "^2.6.0"
+ }
+ },
+ "js2xmlparser": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-3.0.0.tgz",
+ "integrity": "sha1-P7YOqgicVED5MZ9RdgzNB+JJlzM=",
+ "requires": {
+ "xmlcreate": "^1.0.1"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true
+ },
+ "jsdoc": {
+ "version": "3.5.5",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.5.5.tgz",
+ "integrity": "sha512-6PxB65TAU4WO0Wzyr/4/YhlGovXl0EVYfpKbpSroSj0qBxT4/xod/l40Opkm38dRHRdQgdeY836M0uVnJQG7kg==",
+ "requires": {
+ "babylon": "7.0.0-beta.19",
+ "bluebird": "~3.5.0",
+ "catharsis": "~0.8.9",
+ "escape-string-regexp": "~1.0.5",
+ "js2xmlparser": "~3.0.0",
+ "klaw": "~2.0.0",
+ "marked": "~0.3.6",
+ "mkdirp": "~0.5.1",
+ "requizzle": "~0.2.1",
+ "strip-json-comments": "~2.0.1",
+ "taffydb": "2.6.2",
+ "underscore": "~1.8.3"
+ }
+ },
+ "jshint": {
+ "version": "2.9.7",
+ "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.7.tgz",
+ "integrity": "sha512-Q8XN38hGsVQhdlM+4gd1Xl7OB1VieSuCJf+fEJjpo59JH99bVJhXRXAh26qQ15wfdd1VPMuDWNeSWoNl53T4YA==",
+ "dev": true,
+ "requires": {
+ "cli": "~1.0.0",
+ "console-browserify": "1.1.x",
+ "exit": "0.1.x",
+ "htmlparser2": "3.8.x",
+ "lodash": "~4.17.10",
+ "minimatch": "~3.0.2",
+ "shelljs": "0.3.x",
+ "strip-json-comments": "1.0.x"
+ },
+ "dependencies": {
+ "strip-json-comments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+ "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+ "dev": true
+ }
+ }
+ },
+ "jslint": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/jslint/-/jslint-0.12.0.tgz",
+ "integrity": "sha512-RoCsyICcKA+6TFsbys9DpKTfPVaC71Mm5QSjvrWA0lDVN+LIvx6apa42FFisMqmCTvJ8DxkcoQGJ0j7m3kTVow==",
+ "dev": true,
+ "requires": {
+ "exit": "~0.1.2",
+ "glob": "~7.1.2",
+ "nopt": "~3.0.1",
+ "readable-stream": "~2.1.5"
+ },
+ "dependencies": {
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "2.1.5",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz",
+ "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=",
+ "dev": true,
+ "requires": {
+ "buffer-shims": "^1.0.0",
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~1.0.6",
+ "string_decoder": "~0.10.x",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ }
+ }
+ },
+ "json-int64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-int64/-/json-int64-1.0.0.tgz",
+ "integrity": "sha512-yrTg9swToElhEPETLMdZkEzDhbXLs+cxkw/b2rglMPOBlM1DE0utH1EReSMLcnpYJk5iUvD12r0fP2/xHitF5Q==",
+ "requires": {
+ "node-int64": "0.4.0"
+ }
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz",
+ "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=",
+ "dev": true,
+ "requires": {
+ "jsonify": "~0.0.0"
+ }
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "dev": true
+ },
+ "jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "kew": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
+ "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "klaw": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-2.0.0.tgz",
+ "integrity": "sha1-WcEo4Nxc5BAgEVEZTuucv4WGUPY=",
+ "requires": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "kuler": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz",
+ "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==",
+ "dev": true,
+ "requires": {
+ "colornames": "^1.1.1"
+ }
+ },
+ "labeled-stream-splicer": {
+ "version": "2.0.1",
+ "resolved": "http://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz",
+ "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "isarray": "^2.0.4",
+ "stream-splicer": "^2.0.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz",
+ "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==",
+ "dev": true
+ }
+ }
+ },
+ "lazy-cache": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
+ "dev": true
+ },
+ "liftoff": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz",
+ "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=",
+ "dev": true,
+ "requires": {
+ "extend": "^3.0.0",
+ "findup-sync": "^2.0.0",
+ "fined": "^1.0.1",
+ "flagged-respawn": "^1.0.0",
+ "is-plain-object": "^2.0.4",
+ "object.map": "^1.0.0",
+ "rechoir": "^0.6.2",
+ "resolve": "^1.1.7"
+ },
+ "dependencies": {
+ "findup-sync": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+ "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
+ "dev": true,
+ "requires": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^3.1.0",
+ "micromatch": "^3.0.4",
+ "resolve-dir": "^1.0.1"
+ }
+ }
+ }
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+ "dev": true
+ },
+ "lodash.memoize": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz",
+ "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=",
+ "dev": true
+ },
+ "logform": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/logform/-/logform-1.10.0.tgz",
+ "integrity": "sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg==",
+ "dev": true,
+ "requires": {
+ "colors": "^1.2.1",
+ "fast-safe-stringify": "^2.0.4",
+ "fecha": "^2.3.3",
+ "ms": "^2.1.1",
+ "triple-beam": "^1.2.0"
+ },
+ "dependencies": {
+ "colors": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
+ "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ }
+ }
+ },
+ "longest": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
+ "dev": true
+ },
+ "loud-rejection": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+ "dev": true,
+ "requires": {
+ "currently-unhandled": "^0.4.1",
+ "signal-exit": "^3.0.0"
+ }
+ },
+ "make-iterator": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
+ "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.2"
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true
+ },
+ "map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+ "dev": true
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "dev": true,
+ "requires": {
+ "object-visit": "^1.0.0"
+ }
+ },
+ "marked": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
+ "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg=="
+ },
+ "maxmin": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-1.1.0.tgz",
+ "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.0.0",
+ "figures": "^1.0.1",
+ "gzip-size": "^1.0.0",
+ "pretty-bytes": "^1.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "md5.js": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "meow": {
+ "version": "3.7.0",
+ "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+ "dev": true,
+ "requires": {
+ "camelcase-keys": "^2.0.0",
+ "decamelize": "^1.1.2",
+ "loud-rejection": "^1.0.0",
+ "map-obj": "^1.0.1",
+ "minimist": "^1.1.3",
+ "normalize-package-data": "^2.3.4",
+ "object-assign": "^4.0.1",
+ "read-pkg-up": "^1.0.1",
+ "redent": "^1.0.0",
+ "trim-newlines": "^1.0.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "miller-rabin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
+ }
+ },
+ "mime": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz",
+ "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.37.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
+ "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.21",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
+ "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
+ "dev": true,
+ "requires": {
+ "mime-db": "~1.37.0"
+ }
+ },
+ "minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ },
+ "mixin-deep": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "module-deps": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz",
+ "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==",
+ "dev": true,
+ "requires": {
+ "JSONStream": "^1.0.3",
+ "browser-resolve": "^1.7.0",
+ "cached-path-relative": "^1.0.0",
+ "concat-stream": "~1.6.0",
+ "defined": "^1.0.0",
+ "detective": "^5.0.2",
+ "duplexer2": "^0.1.2",
+ "inherits": "^2.0.1",
+ "parents": "^1.0.0",
+ "readable-stream": "^2.0.2",
+ "resolve": "^1.4.0",
+ "stream-combiner2": "^1.1.1",
+ "subarg": "^1.0.0",
+ "through2": "^2.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ }
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "node-gyp-build": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz",
+ "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w=="
+ },
+ "node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs="
+ },
+ "nopt": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
+ "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
+ "requires": {
+ "abbrev": "1",
+ "osenv": "^0.1.4"
+ }
+ },
+ "normalize-package-data": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "is-builtin-module": "^1.0.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.defaults": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
+ "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
+ "dev": true,
+ "requires": {
+ "array-each": "^1.0.1",
+ "array-slice": "^1.0.0",
+ "for-own": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
+ "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
+ "dev": true,
+ "requires": {
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "one-time": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz",
+ "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=",
+ "dev": true
+ },
+ "os-browserify": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+ "dev": true
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
+ },
+ "osenv": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+ "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
+ "requires": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
+ }
+ },
+ "p-each-series": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz",
+ "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=",
+ "dev": true,
+ "requires": {
+ "p-reduce": "^1.0.0"
+ }
+ },
+ "p-reduce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz",
+ "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=",
+ "dev": true
+ },
+ "pako": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz",
+ "integrity": "sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ==",
+ "dev": true
+ },
+ "parents": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz",
+ "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=",
+ "dev": true,
+ "requires": {
+ "path-platform": "~0.11.15"
+ }
+ },
+ "parse-asn1": {
+ "version": "5.1.1",
+ "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
+ "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
+ "dev": true,
+ "requires": {
+ "asn1.js": "^4.0.0",
+ "browserify-aes": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3"
+ }
+ },
+ "parse-filepath": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
+ "dev": true,
+ "requires": {
+ "is-absolute": "^1.0.0",
+ "map-cache": "^0.2.0",
+ "path-root": "^0.1.1"
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+ "dev": true
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true
+ },
+ "path-browserify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
+ "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "dev": true,
+ "requires": {
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "dev": true
+ },
+ "path-platform": {
+ "version": "0.11.15",
+ "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz",
+ "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=",
+ "dev": true
+ },
+ "path-root": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
+ "dev": true,
+ "requires": {
+ "path-root-regex": "^0.1.0"
+ }
+ },
+ "path-root-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
+ "dev": true
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "pbkdf2": {
+ "version": "3.0.17",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
+ "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
+ "dev": true,
+ "requires": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "dev": true
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+ "dev": true
+ },
+ "phantom": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/phantom/-/phantom-6.0.3.tgz",
+ "integrity": "sha512-8bb8urWoUiZ0E+JC4goaYBDPxljTnnxGwogz5cvash2SQovf//QAPoshXQz06kY/tpI+5caBVng0K0oZkVMNIQ==",
+ "dev": true,
+ "requires": {
+ "phantomjs-prebuilt": "^2.1.16",
+ "split": "^1.0.1",
+ "winston": "^3.0.0"
+ }
+ },
+ "phantomjs-prebuilt": {
+ "version": "2.1.16",
+ "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
+ "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "^4.0.3",
+ "extract-zip": "^1.6.5",
+ "fs-extra": "^1.0.0",
+ "hasha": "^2.2.0",
+ "kew": "^0.7.0",
+ "progress": "^1.1.8",
+ "request": "^2.81.0",
+ "request-progress": "^2.0.1",
+ "which": "^1.2.10"
+ },
+ "dependencies": {
+ "progress": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+ "dev": true
+ }
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true
+ },
+ "pretty-bytes": {
+ "version": "1.0.4",
+ "resolved": "http://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
+ "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^4.0.1",
+ "meow": "^3.1.0"
+ }
+ },
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+ "dev": true
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "proxy-from-env": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
+ "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
+ "dev": true
+ },
+ "psl": {
+ "version": "1.1.31",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
+ "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==",
+ "dev": true
+ },
+ "public-encrypt": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+ "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ },
+ "puppeteer": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.11.0.tgz",
+ "integrity": "sha512-iG4iMOHixc2EpzqRV+pv7o3GgmU2dNYEMkvKwSaQO/vMZURakwSOn/EYJ6OIRFYOque1qorzIBvrytPIQB3YzQ==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0",
+ "extract-zip": "^1.6.6",
+ "https-proxy-agent": "^2.2.1",
+ "mime": "^2.0.3",
+ "progress": "^2.0.1",
+ "proxy-from-env": "^1.0.0",
+ "rimraf": "^2.6.1",
+ "ws": "^6.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ }
+ }
+ },
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+ "dev": true
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+ "dev": true
+ },
+ "querystring-es3": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+ "dev": true
+ },
+ "randombytes": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
+ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "randomfill": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "read-only-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz",
+ "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "dev": true,
+ "requires": {
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.1.6"
+ }
+ },
+ "redent": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+ "dev": true,
+ "requires": {
+ "indent-string": "^2.1.0",
+ "strip-indent": "^1.0.1"
+ }
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "repeat-element": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
+ },
+ "repeating": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+ "dev": true,
+ "requires": {
+ "is-finite": "^1.0.0"
+ }
+ },
+ "request": {
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.0",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.4.3",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "request-progress": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
+ "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=",
+ "dev": true,
+ "requires": {
+ "throttleit": "^1.0.0"
+ }
+ },
+ "requizzle": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.1.tgz",
+ "integrity": "sha1-aUPDUwxNmn5G8c3dUcFY/GcM294=",
+ "requires": {
+ "underscore": "~1.6.0"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
+ "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag="
+ }
+ }
+ },
+ "resolve": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz",
+ "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ },
+ "resolve-dir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
+ }
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "dev": true
+ },
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true
+ },
+ "right-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+ "dev": true,
+ "requires": {
+ "align-text": "^0.1.1"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.5"
+ }
+ },
+ "ripemd160": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "requires": {
+ "ret": "~0.1.10"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
+ "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
+ "dev": true
+ },
+ "set-value": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "sha.js": {
+ "version": "2.4.11",
+ "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "shasum": {
+ "version": "1.0.2",
+ "resolved": "http://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz",
+ "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=",
+ "dev": true,
+ "requires": {
+ "json-stable-stringify": "~0.0.0",
+ "sha.js": "~2.4.4"
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "shell-quote": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz",
+ "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=",
+ "dev": true,
+ "requires": {
+ "array-filter": "~0.0.0",
+ "array-map": "~0.0.0",
+ "array-reduce": "~0.0.0",
+ "jsonify": "~0.0.0"
+ }
+ },
+ "shelljs": {
+ "version": "0.3.0",
+ "resolved": "http://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
+ "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "simple-concat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
+ "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=",
+ "dev": true
+ },
+ "simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.3.1"
+ },
+ "dependencies": {
+ "is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "requires": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.2.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "source-map-resolve": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+ "dev": true,
+ "requires": {
+ "atob": "^2.1.1",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+ "dev": true
+ },
+ "spdx-correct": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+ "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
+ "dev": true,
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+ "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz",
+ "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==",
+ "dev": true
+ },
+ "split": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
+ "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
+ "dev": true,
+ "requires": {
+ "through": "2"
+ }
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz",
+ "integrity": "sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==",
+ "dev": true,
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "stack-trace": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+ "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
+ "dev": true
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "requires": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "stream-browserify": {
+ "version": "2.0.1",
+ "resolved": "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
+ "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.1",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "stream-combiner2": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
+ "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=",
+ "dev": true,
+ "requires": {
+ "duplexer2": "~0.1.0",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "stream-http": {
+ "version": "2.8.3",
+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
+ "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
+ "dev": true,
+ "requires": {
+ "builtin-status-codes": "^3.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.3.6",
+ "to-arraybuffer": "^1.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "stream-splicer": {
+ "version": "2.0.0",
+ "resolved": "http://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz",
+ "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "string_decoder": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
+ "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "dev": true,
+ "requires": {
+ "is-utf8": "^0.2.0"
+ }
+ },
+ "strip-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^4.0.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
+ },
+ "subarg": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
+ "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.1.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "syntax-error": {
+ "version": "1.4.0",
+ "resolved": "http://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz",
+ "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.2.0"
+ }
+ },
+ "taffydb": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
+ "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg="
+ },
+ "text-hex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
+ "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==",
+ "dev": true
+ },
+ "throttleit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+ "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "timers-browserify": {
+ "version": "1.4.2",
+ "resolved": "http://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
+ "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=",
+ "dev": true,
+ "requires": {
+ "process": "~0.11.0"
+ }
+ },
+ "to-arraybuffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+ "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+ "dev": true
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+ "dev": true,
+ "requires": {
+ "psl": "^1.1.24",
+ "punycode": "^1.4.1"
+ }
+ },
+ "trim-newlines": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+ "dev": true
+ },
+ "triple-beam": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
+ "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==",
+ "dev": true
+ },
+ "tty-browserify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
+ "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
+ "typescript": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz",
+ "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==",
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "2.6.4",
+ "resolved": "http://registry.npmjs.org/uglify-js/-/uglify-js-2.6.4.tgz",
+ "integrity": "sha1-ZeovswWck5RpLxX+2HwrNsFrmt8=",
+ "dev": true,
+ "requires": {
+ "async": "~0.2.6",
+ "source-map": "~0.5.1",
+ "uglify-to-browserify": "~1.0.0",
+ "yargs": "~3.10.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.2.10",
+ "resolved": "http://registry.npmjs.org/async/-/async-0.2.10.tgz",
+ "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
+ "dev": true
+ }
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+ "dev": true
+ },
+ "umd": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz",
+ "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==",
+ "dev": true
+ },
+ "unc-path-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
+ "dev": true
+ },
+ "undeclared-identifiers": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz",
+ "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==",
+ "dev": true,
+ "requires": {
+ "acorn-node": "^1.3.0",
+ "get-assigned-identifiers": "^1.2.0",
+ "simple-concat": "^1.0.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "underscore": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
+ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
+ },
+ "underscore-contrib": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/underscore-contrib/-/underscore-contrib-0.3.0.tgz",
+ "integrity": "sha1-ZltmwkeD+PorGMn4y7Dix9SMJsc=",
+ "requires": {
+ "underscore": "1.6.0"
+ },
+ "dependencies": {
+ "underscore": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
+ "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag="
+ }
+ }
+ },
+ "underscore.string": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",
+ "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "^1.0.3",
+ "util-deprecate": "^1.0.2"
+ }
+ },
+ "union-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^0.4.3"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "set-value": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.1",
+ "to-object-path": "^0.3.0"
+ }
+ }
+ }
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "requires": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true
+ }
+ }
+ },
+ "uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ }
+ }
+ },
+ "uri-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz",
+ "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=",
+ "dev": true
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "dev": true
+ },
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+ "dev": true
+ }
+ }
+ },
+ "use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true
+ },
+ "util": {
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+ "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+ "dev": true
+ },
+ "v8flags": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.2.tgz",
+ "integrity": "sha512-MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw==",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "vm-browserify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz",
+ "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==",
+ "dev": true
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+ "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+ "dev": true
+ },
+ "winston": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/winston/-/winston-3.1.0.tgz",
+ "integrity": "sha512-FsQfEE+8YIEeuZEYhHDk5cILo1HOcWkGwvoidLrDgPog0r4bser1lEIOco2dN9zpDJ1M88hfDgZvxe5z4xNcwg==",
+ "dev": true,
+ "requires": {
+ "async": "^2.6.0",
+ "diagnostics": "^1.1.1",
+ "is-stream": "^1.1.0",
+ "logform": "^1.9.1",
+ "one-time": "0.0.4",
+ "readable-stream": "^2.3.6",
+ "stack-trace": "0.0.x",
+ "triple-beam": "^1.3.0",
+ "winston-transport": "^4.2.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
+ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.10"
+ }
+ }
+ }
+ },
+ "winston-transport": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz",
+ "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.3.6",
+ "triple-beam": "^1.2.0"
+ }
+ },
+ "wordwrap": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "ws": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.3.tgz",
+ "integrity": "sha512-tbSxiT+qJI223AP4iLfQbkbxkwdFcneYinM2+x46Gx2wgvbaOMO36czfdfVUBRTHvzAMRhDd98sA5d/BuWbQdg==",
+ "dev": true,
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ },
+ "xmlcreate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-1.0.2.tgz",
+ "integrity": "sha1-+mv3YqYKQT+z3Y9LA8WyaSONMI8="
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "3.10.0",
+ "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^1.0.2",
+ "cliui": "^2.1.0",
+ "decamelize": "^1.0.0",
+ "window-size": "0.1.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+ "dev": true
+ }
+ }
+ },
+ "yauzl": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+ "dev": true,
+ "requires": {
+ "fd-slicer": "~1.0.1"
+ }
+ }
+ }
+}
diff --git a/lib/ts/package.json b/lib/ts/package.json
new file mode 100644
index 0000000..eda1c0a
--- /dev/null
+++ b/lib/ts/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "thrift",
+ "version": "0.13.0",
+ "description": "Thrift is a software framework for scalable cross-language services development.",
+ "author": {
+ "name": "Apache Thrift Developers",
+ "email": "dev@thrift.apache.org"
+ },
+ "bugs": "https://issues.apache.org/jira/projects/THRIFT/summary",
+ "homepage": "http://thrift.apache.org",
+ "repository": "https://github.com/apache/thrift",
+ "license": "Apache-2.0",
+ "devDependencies": {
+ "@types/node-int64": "^0.4.29",
+ "@types/phantom": "^3.2.5",
+ "@types/qunit": "^2.5.4",
+ "browserify": "^16.2.3",
+ "bufferutil": "^4.0.1",
+ "grunt": "^1.0.3",
+ "grunt-cli": "^1.2.0",
+ "grunt-contrib-concat": "^1.0.1",
+ "grunt-contrib-jshint": "^1.0.0",
+ "grunt-contrib-qunit": "^3.1.0",
+ "grunt-contrib-uglify": "^1.0.1",
+ "grunt-jsdoc": "^2.2.1",
+ "grunt-shell-spawn": "^0.3.12",
+ "jslint": "^0.12.0",
+ "node-int64": "^0.4.0",
+ "phantom": "^6.0.3",
+ "typescript": "^3.2.4"
+ },
+ "dependencies": {
+ "bufferutil": "^4.0.1",
+ "jsdoc": "^3.5.5",
+ "json-int64": "^1.0.0",
+ "nopt": "^4.0.1"
+ },
+ "types": "./thrift.d.ts"
+}
diff --git a/lib/ts/test/build.xml b/lib/ts/test/build.xml
new file mode 100755
index 0000000..5c3a4a8
--- /dev/null
+++ b/lib/ts/test/build.xml
@@ -0,0 +1,250 @@
+<!--
+ 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.
+-->
+<project name="Java Script Test" default="test" basedir="."
+ xmlns:artifact="antlib:org.apache.maven.artifact.ant"
+ xmlns:jsl="antlib:com.googlecode.jslint4java">
+
+ <description>Java Script Test based on Thrift Java Library</description>
+
+ <property name="src" location="src" />
+ <property name="genjava" location="gen-java" />
+ <property name="genjs" location="gen-js" />
+ <property name="build" location="build" />
+ <property name="jar.file" location="${build}/jstest.jar" />
+
+ <!-- the root directory, where you unpack thrift distibution (e.g.: thrift-0.x.x.tar.gz) -->
+ <property name="thrift.dir" location="../../../" />
+ <property name="thrift.java.dir" location="${thrift.dir}/lib/java" />
+ <property name="build.tools.dir" location="${thrift.java.dir}/build/tools/"/>
+ <property file="${basedir}/build.properties"/>
+
+ <!-- Include the base Java properties file -->
+ <property file="${thrift.java.dir}/gradle.properties" />
+
+ <property name="thrift.compiler" location="${thrift.dir}/compiler/cpp/thrift" />
+
+ <path id="libs.classpath">
+ <fileset dir="${thrift.java.dir}/build/libs">
+ <include name="libthrift*.jar" />
+ <exclude name="libthrift*javadoc.jar" />
+ <exclude name="libthrift*sources.jar" />
+ </fileset>
+ <fileset dir="${thrift.java.dir}/build/deps">
+ <include name="*.jar" />
+ </fileset>
+ <fileset dir="${build}/lib">
+ <include name="*.jar" />
+ </fileset>
+ </path>
+
+ <path id="test.classpath">
+ <path refid="libs.classpath" />
+ <pathelement location="${jar.file}" />
+ </path>
+
+ <target name="dependencies">
+ <fail>
+ <condition>
+ <not>
+ <resourcecount count="2">
+ <fileset id="fs" dir="${thrift.java.dir}/build/libs">
+ <include name="libthrift*.jar" />
+ <exclude name="libthrift*javadoc.jar" />
+ <exclude name="libthrift*sources.jar" />
+ </fileset>
+ </resourcecount>
+ </not>
+ </condition>
+ You need libthrift*.jar and libthrift*test.jar located at
+ ${thrift.java.dir}/build/libs
+ Did you compile Thrift Java library and its test suite by "ant compile-test"?
+ </fail>
+ <fail>
+ <condition>
+ <not>
+ <resourcecount count="1">
+ <fileset id="fs" dir="${thrift.dir}" includes="compiler/cpp/thrift"/>
+ </resourcecount>
+ </not>
+ </condition>
+ Thrift compiler is missing !
+ </fail>
+ </target>
+
+ <target name="init" depends="dependencies">
+ <tstamp />
+ <mkdir dir="${build.tools.dir}"/>
+ <mkdir dir="${build}"/>
+ <mkdir dir="${build}/js/lib"/>
+ <mkdir dir="${build}/lib"/>
+ <mkdir dir="${build}/log"/>
+ <mkdir dir="${build}/test"/>
+ <mkdir dir="${build}/test/log"/>
+ </target>
+
+ <target name="download_jslibs">
+ <get src="http://code.jquery.com/jquery-1.11.3.min.js" dest="${build}/js/lib/jquery.js" usetimestamp="true"/>
+ <get src="http://code.jquery.com/qunit/qunit-2.6.2.js" dest="${build}/js/lib/qunit.js" usetimestamp="true"/>
+ <get src="http://code.jquery.com/qunit/qunit-2.6.2.css" dest="${build}/js/lib/qunit.css" usetimestamp="true"/>
+ <get src="http://code.jquery.com/qunit/qunit-2.6.2.js" dest="${build}/ts/qunit.js" usetimestamp="true"/>
+ <get src="http://code.jquery.com/qunit/qunit-2.6.2.css" dest="${build}/ts/qunit.css" usetimestamp="true"/>
+ </target>
+
+ <target name="jslibs" depends="init, proxy, download_jslibs">
+ </target>
+
+ <target name="compile" description="compile the test suite" depends="init, generate, resolve">
+ <!-- //TODO enable <compilerarg value="-Xlint"/>-->
+ <javac compiler="modern" includeantruntime="false" srcdir="${genjava}" destdir="${build}/test" classpathref="libs.classpath"/>
+ <javac compiler="modern" includeantruntime="false" srcdir="${src}" destdir="${build}/test" classpathref="libs.classpath"/>
+ </target>
+
+ <target name="jstest" description="create the test suite jar file" depends="compile">
+ <jar jarfile="${jar.file}" basedir="${build}/test"/>
+ </target>
+
+ <target name="testserver" description="run the test server" depends="jstest, jslibs">
+ <java classname="test.Httpd" fork="true"
+ classpathref="test.classpath" failonerror="true">
+ <arg value="../" />
+ </java>
+ </target>
+
+ <target name="proxy" if="proxy.enabled">
+ <setproxy proxyhost="${proxy.host}" proxyport="${proxy.port}"
+ proxyuser="${proxy.user}" proxypassword="${proxy.pass}"/>
+ </target>
+
+ <target name="xvfb">
+ <echo>check if Xvfb is available:</echo>
+ <exec executable="Xvfb" failifexecutionfails="no" resultproperty="xvfb.present" failonerror="false" output="${build}/log/xvfb.log">
+ <arg line="--version"/>
+ </exec>
+ </target>
+
+ <target name="phantomjs" depends="xvfb" if="xvfb.present">
+ <echo>check if phantomjs is available:</echo>
+ <exec executable="phantomjs" failifexecutionfails="no" resultproperty="phantomjs.present" failonerror="false" output="${build}/log/phantomjs.log">
+ <arg line="--version"/>
+ </exec>
+ </target>
+
+ <target name="unittest" description="do unit tests with headless browser phantomjs" depends="init, phantomjs, jstest, jslibs" if="phantomjs.present">
+ <parallel>
+ <exec executable="Xvfb" spawn="true" failonerror="false">
+ <arg line=":99" />
+ </exec>
+ <java classname="test.Httpd" fork="true" timeout="10000"
+ classpathref="test.classpath" failonerror="false" output="${build}/log/unittest.log">
+ <arg value="../" />
+ </java>
+ <sequential>
+ <sleep seconds="2"/>
+ <echo>Running Unit Tests with headless browser!</echo>
+ <exec executable="phantomjs" failonerror="true">
+ <env key="DISPLAY" value=":99"/>
+ <arg line="phantomjs-qunit.js http://localhost:8088/test/test.html" />
+ </exec>
+ </sequential>
+ </parallel>
+ </target>
+
+ <target name="generate">
+ <exec executable="${thrift.compiler}" failonerror="true">
+ <arg line="--gen java ${thrift.dir}/test/ThriftTest.thrift" />
+ </exec>
+ <exec executable="${thrift.compiler}" failonerror="true">
+ <arg line="--gen js:jquery ${thrift.dir}/test/ThriftTest.thrift" />
+ </exec>
+ <exec executable="${thrift.compiler}" failonerror="true">
+ <arg line="--gen js:jquery ${thrift.dir}/test/DoubleConstantsTest.thrift" />
+ </exec>
+ </target>
+
+ <target name="test" description="run test suite (lint, unittest)" depends="lint, unittest"/>
+
+ <target name="lint" description="code quality checks (jslint and gjslint if available)" depends="generate, gjslint, jslint"/>
+
+ <target name="jslint" depends="resolve">
+ <taskdef uri="antlib:com.googlecode.jslint4java" resource="com/googlecode/jslint4java/antlib.xml" classpathref="libs.classpath" />
+ <!--
+ the following options would probably make sense in the future:
+ browser,undef,eqeqeq,plusplus,bitwise,regexp,strict,newcap,immed
+ -->
+ <jsl:jslint options="evil,forin,browser,bitwise,regexp,newcap,immed" encoding="UTF-8">
+ <formatter type="plain" />
+ <fileset dir="../src" includes="thrift.js" />
+
+ <!-- issues with unsafe character -->
+ <!-- fileset dir="." includes="*test*.js" /> -->
+ </jsl:jslint>
+ </target>
+
+ <target name="check-gjslint">
+ <echo>check if gjslint is available:</echo>
+ <exec executable="gjslint" failifexecutionfails="no" resultproperty="gjslint.present" failonerror="false">
+ <arg line="--helpshort"/>
+ </exec>
+ </target>
+
+ <target name="gjslint" depends="check-gjslint" if="gjslint.present">
+ <exec executable="gjslint" failifexecutionfails="no">
+ <arg line="--nojsdoc"/>
+ <arg line="${genjs}/*.js"/>
+ <arg line="../src/thrift.js"/>
+
+ <!-- issues with unsafe character, etc. -->
+ <!-- <arg line="*test*.js"/> -->
+ </exec>
+ </target>
+
+ <target name="clean">
+ <delete dir="${build}" />
+ <delete dir="${genjava}" />
+ <delete dir="${genjs}" />
+ </target>
+
+ <target name="mvn.ant.tasks.download" depends="init,mvn.ant.tasks.check" unless="mvn.ant.tasks.found">
+ <get src="${mvn.ant.task.url}/${mvn.ant.task.jar}" dest="${build.tools.dir}/${mvn.ant.task.jar}" usetimestamp="true"/>
+ </target>
+
+ <target name="mvn.ant.tasks.check">
+ <condition property="mvn.ant.tasks.found">
+ <typefound uri="antlib:org.apache.maven.artifact.ant" name="artifact"/>
+ </condition>
+ </target>
+
+ <target name="resolve" depends="mvn.ant.tasks.download" unless="mvn.finished">
+ <typedef uri="antlib:org.apache.maven.artifact.ant" classpath="${thrift.java.dir}/build/tools/${mvn.ant.task.jar}"/>
+
+ <artifact:dependencies filesetId="js.test.dependency.jars">
+ <dependency groupId="org.apache.httpcomponents" artifactId="httpclient" version="4.0.1"/>
+ <dependency groupId="com.googlecode.jslint4java" artifactId="jslint4java-ant" version="1.4.6"/>
+ <dependency groupId="eu.medsea.mimeutil" artifactId="mime-util" version="2.1.3"/>
+ </artifact:dependencies>
+
+ <!-- Copy the dependencies to the build/lib dir -->
+ <copy todir="${build}/lib">
+ <fileset refid="js.test.dependency.jars"/>
+ <mapper type="flatten"/>
+ </copy>
+
+ <property name="mvn.finished" value="true"/>
+ </target>
+</project>
diff --git a/lib/ts/test/phantom-client.ts b/lib/ts/test/phantom-client.ts
new file mode 100644
index 0000000..5518937
--- /dev/null
+++ b/lib/ts/test/phantom-client.ts
@@ -0,0 +1,352 @@
+/*
+ * 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.
+ */
+ /* jshint -W100 */
+
+import { ThriftTest } from "./gen-js/ThriftTest_types";
+import "./gen-js/ThriftTest";
+var Int64 = require("node-int64");
+var phantom = require("phantom");
+
+const int64_2_pow_60: typeof Int64 = new Int64('1000000000000000');
+const int64_minus_2_pow_60: typeof Int64 = new Int64('f000000000000000');
+
+ (function() {
+ 'use strict';
+
+ // Rudimentary test helper functions
+ // TODO: Return error code based on kind of errors rather than throw
+ var ok = function(t, msg) {
+ if (!t) {
+ console.log('*** FAILED ***');
+ throw new Error(msg);
+ }
+ };
+ var equal = function(a, b) {
+ if (a !== b) {
+ console.log('*** FAILED ***');
+ throw new Error();
+ }
+ };
+ var test = function(name, f) {
+ console.log('TEST : ' + name);
+ f();
+ console.log('OK\n');
+ };
+
+ var parseArgs = function(args) {
+ var skips = [
+ '--transport=http',
+ '--protocol=json'
+ ];
+ var opts = {
+ port: '9090'
+ // protocol: 'json',
+ };
+ var keys = {};
+ for (var key in opts) {
+ keys['--' + key + '='] = key;
+ }
+ for (var i in args) {
+ var arg = args[i];
+ if (skips.indexOf(arg) != -1) {
+ continue;
+ }
+ var hit = false;
+ for (var k in keys) {
+ if (arg.slice(0, k.length) === k) {
+ opts[keys[k]] = arg.slice(k.length);
+ hit = true;
+ break;
+ }
+ }
+ if (!hit) {
+ throw new Error('Unknown argument: ' + arg);
+ }
+ }
+ var portAsInt: number = parseInt(opts.port, 10);
+ if (!opts.port || portAsInt < 1 || portAsInt > 65535) {
+ throw new Error('Invalid port number');
+ }
+ return opts;
+ };
+
+ var execute = function() {
+ console.log('### Apache Thrift Javascript standalone test client');
+ console.log('------------------------------------------------------------');
+
+ phantom.page.injectJs('thrift.js');
+ phantom.page.injectJs('gen-js/ThriftTest_types.js');
+ phantom.page.injectJs('gen-js/ThriftTest.js');
+
+ var system = require('system');
+ var opts = parseArgs(system.args.slice(1));
+ var port = opts.port;
+ var transport = new Thrift.Transport('http://localhost:' + port + '/service');
+ var protocol = new Thrift.Protocol(transport);
+ var client = new ThriftTest.ThriftTestClient(protocol);
+
+
+ // TODO: Remove duplicate code with test.js.
+ // all Languages in UTF-8
+ var stringTest = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski, Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia, Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa, ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар, Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, Bahasa Melayu, مازِرونی, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, Norsk (nynorsk), Norsk (bokmål), Nouormand, Diné bizaad, Occitan, Иронау, Papiamentu, Deitsch, Norfuk / Pitkern, Polski, پنجابی, پښتو, Português, Runa Simi, Rumantsch, Romani, Română, Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk, Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog, Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, Bân-lâm-gú, 粵語";
+
+ function checkRecursively(map1, map2) {
+ if (typeof map1 !== 'function' && typeof map2 !== 'function') {
+ if (!map1 || typeof map1 !== 'object') {
+ equal(map1, map2);
+ } else {
+ for (var key in map1) {
+ checkRecursively(map1[key], map2[key]);
+ }
+ }
+ }
+ }
+
+ test('Void', function() {
+ equal(client.testVoid(), undefined);
+ });
+ test('Binary (String)', function() {
+ var binary: string = '';
+ for (var v = 255; v >= 0; --v) {
+ binary += String.fromCharCode(v);
+ }
+ equal(client.testBinary(binary), binary);
+ });
+ test('Binary (Uint8Array)', function() {
+ var binary: string = '';
+ for (var v = 255; v >= 0; --v) {
+ binary += String.fromCharCode(v);
+ }
+ var arr = new Uint8Array(binary.length);
+ for (var i = 0; i < binary.length; ++i) {
+ arr[i] = binary[i].charCodeAt(0);
+ }
+ const hexEncodedString = Array.from(arr, function(byte) {
+ return String.fromCharCode(byte);
+ }).join('')
+ equal(client.testBinary(hexEncodedString), binary);
+ });
+ test('String', function() {
+ equal(client.testString(''), '');
+ equal(client.testString(stringTest), stringTest);
+
+ var specialCharacters = 'quote: \" backslash:' +
+ ' forwardslash-escaped: \/ ' +
+ ' backspace: \b formfeed: \f newline: \n return: \r tab: ' +
+ ' now-all-of-them-together: "\\\/\b\n\r\t' +
+ ' now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><';
+ equal(client.testString(specialCharacters), specialCharacters);
+ });
+ test('Double', function() {
+ equal(client.testDouble(0), 0);
+ equal(client.testDouble(-1), -1);
+ equal(client.testDouble(3.14), 3.14);
+ equal(client.testDouble(Math.pow(2, 60)), Math.pow(2, 60));
+ });
+ test('Bool', function() {
+ equal(client.testBool(true), true);
+ equal(client.testBool(false), false);
+ });
+ test('I8', function() {
+ equal(client.testByte(0), 0);
+ equal(client.testByte(0x01), 0x01);
+ });
+ test('I32', function() {
+ equal(client.testI32(0), 0);
+ equal(client.testI32(Math.pow(2, 30)), Math.pow(2, 30));
+ equal(client.testI32(-Math.pow(2, 30)), -Math.pow(2, 30));
+ });
+ test('I64', function() {
+ equal(client.testI64(new Int64(0)), 0);
+ equal(client.testI64(int64_2_pow_60), Math.pow(2, 52));
+ equal(client.testI64(int64_minus_2_pow_60), -Math.pow(2, 52));
+ });
+
+ test('Struct', function() {
+ var structTestInput: ThriftTest.Xtruct = new ThriftTest.Xtruct();
+ structTestInput.string_thing = 'worked';
+ structTestInput.byte_thing = 0x01;
+ structTestInput.i32_thing = Math.pow(2, 30);
+ structTestInput.i64_thing = int64_2_pow_60;
+
+ var structTestOutput: ThriftTest.Xtruct = client.testStruct(structTestInput);
+
+ equal(structTestOutput.string_thing, structTestInput.string_thing);
+ equal(structTestOutput.byte_thing, structTestInput.byte_thing);
+ equal(structTestOutput.i32_thing, structTestInput.i32_thing);
+ equal(structTestOutput.i64_thing, structTestInput.i64_thing);
+
+ equal(JSON.stringify(structTestOutput), JSON.stringify(structTestInput));
+ });
+
+ test('Nest', function() {
+ var xtrTestInput: ThriftTest.Xtruct = new ThriftTest.Xtruct();
+ xtrTestInput.string_thing = 'worked';
+ xtrTestInput.byte_thing = 0x01;
+ xtrTestInput.i32_thing = Math.pow(2, 30);
+ xtrTestInput.i64_thing = int64_2_pow_60;
+
+ var nestTestInput: ThriftTest.Xtruct2 = new ThriftTest.Xtruct2();
+ nestTestInput.byte_thing = 0x02;
+ nestTestInput.struct_thing = xtrTestInput;
+ nestTestInput.i32_thing = Math.pow(2, 15);
+
+ var nestTestOutput = client.testNest(nestTestInput);
+
+ equal(nestTestOutput.byte_thing, nestTestInput.byte_thing);
+ equal(nestTestOutput.struct_thing.string_thing, nestTestInput.struct_thing.string_thing);
+ equal(nestTestOutput.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing);
+ equal(nestTestOutput.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing);
+ equal(nestTestOutput.struct_thing.i64_thing, nestTestInput.struct_thing.i64_thing);
+ equal(nestTestOutput.i32_thing, nestTestInput.i32_thing);
+
+ equal(JSON.stringify(nestTestOutput), JSON.stringify(nestTestInput));
+ });
+
+ test('Map', function() {
+ var mapTestInput: {[k: number]: number;} = {7: 77, 8: 88, 9: 99};
+
+ var mapTestOutput: {[k: number]: number;} = client.testMap(mapTestInput);
+
+ for (var key in mapTestOutput) {
+ equal(mapTestOutput[key], mapTestInput[key]);
+ }
+ });
+
+ test('StringMap', function() {
+ var mapTestInput: {[k: string]: string;} = {
+ 'a': '123', 'a b': 'with spaces ', 'same': 'same', '0': 'numeric key',
+ 'longValue': stringTest, stringTest: 'long key'
+ };
+
+ var mapTestOutput: {[k: string]: string;} = client.testStringMap(mapTestInput);
+
+ for (var key in mapTestOutput) {
+ equal(mapTestOutput[key], mapTestInput[key]);
+ }
+ });
+
+ test('Set', function() {
+ var setTestInput: number[] = [1, 2, 3];
+ ok(client.testSet(setTestInput), setTestInput);
+ });
+
+ test('List', function() {
+ var listTestInput: number[] = [1, 2, 3];
+ ok(client.testList(listTestInput), listTestInput);
+ });
+
+ test('Enum', function() {
+ equal(client.testEnum(ThriftTest.Numberz.ONE), ThriftTest.Numberz.ONE);
+ });
+
+ test('TypeDef', function() {
+ equal(client.testTypedef(new Int64(69)), 69);
+ });
+
+ test('MapMap', function() {
+ var mapMapTestExpectedResult: {[K: number]: {[k: number]: number}} = {
+ '4': {'1': 1, '2': 2, '3': 3, '4': 4},
+ '-4': {'-4': -4, '-3': -3, '-2': -2, '-1': -1}
+ };
+
+ var mapMapTestOutput = client.testMapMap(1);
+
+
+ for (var key in mapMapTestOutput) {
+ for (var key2 in mapMapTestOutput[key]) {
+ equal(mapMapTestOutput[key][key2], mapMapTestExpectedResult[key][key2]);
+ }
+ }
+
+ checkRecursively(mapMapTestOutput, mapMapTestExpectedResult);
+ });
+
+ test('Xception', function() {
+ try {
+ client.testException('Xception');
+ ok(false, "expected an exception but there was no exception");
+ } catch (e) {
+ equal(e.errorCode, 1001);
+ equal(e.message, 'Xception');
+ }
+ });
+
+ test('no Exception', function() {
+ try {
+ client.testException('no Exception');
+ } catch (e) {
+ ok(false, "expected no exception but here was an exception");
+ }
+ });
+
+ test('TException', function() {
+ try {
+ client.testException('TException');
+ ok(false, "expected an exception but there was no exception");
+ } catch (e) {
+ ok(ok, "succesfully got exception");
+ }
+ });
+
+ const crazy: ThriftTest.Insanity = {
+ 'userMap': { '5': new Int64(5), '8': new Int64(8) },
+ 'xtructs': [{
+ 'string_thing': 'Goodbye4',
+ 'byte_thing': 4,
+ 'i32_thing': 4,
+ 'i64_thing': new Int64(4)
+ },
+ {
+ 'string_thing': 'Hello2',
+ 'byte_thing': 2,
+ 'i32_thing': 2,
+ 'i64_thing': new Int64(2)
+ }]
+ };
+ test('Insanity', function() {
+ const insanity: {[k: number]: (ThriftTest.Insanity | {[k:number]: ThriftTest.Insanity})} = {
+ '1': {
+ '2': crazy,
+ '3': crazy
+ },
+ '2': { '6': new ThriftTest.Insanity() }
+ };
+ var res = client.testInsanity(new ThriftTest.Insanity(crazy));
+ ok(res, JSON.stringify(res));
+ ok(insanity, JSON.stringify(insanity));
+
+ checkRecursively(res, insanity);
+ });
+
+ console.log('------------------------------------------------------------');
+ console.log('### All tests succeeded.');
+ return 0;
+ };
+
+ try {
+ var ret = execute();
+ phantom.exit(ret);
+ } catch (err) {
+ // Catch all and exit to avoid hang.
+ console.error(err);
+ phantom.exit(1);
+ }
+ })();
+
\ No newline at end of file
diff --git a/lib/ts/test/server_http.js b/lib/ts/test/server_http.js
new file mode 100644
index 0000000..8380c3a
--- /dev/null
+++ b/lib/ts/test/server_http.js
@@ -0,0 +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.
+ */
+
+// This HTTP server is designed to serve the test.html browser
+// based JavaScript test page (which must be in the current directory).
+// This server also supplies the Thrift based test service, which depends
+// on the standard ThriftTest.thrift IDL service (which must be compiled
+// for Node and browser based JavaScript in ./gen-nodejs and ./gen-js
+// respectively).
+//
+// Using the command flag --es6, this server can be run using nodejs code built
+// for the es6 environment or for pre-es6 environment.
+//
+
+const thrift = require('../../nodejs/lib/thrift');
+const es6Mode = process.argv.includes('--es6');
+const genFolder = es6Mode ? 'gen-nodejs-es6' : 'gen-nodejs';
+const ThriftTestSvc = require(`./${genFolder}/ThriftTest.js`);
+const ThriftTestHandler = require('./test_handler').ThriftTestHandler;
+
+const ThriftTestSvcOpt = {
+ transport: thrift.TBufferedTransport,
+ protocol: thrift.TJSONProtocol,
+ processor: ThriftTestSvc,
+ handler: ThriftTestHandler
+};
+
+const ThriftWebServerOptions = {
+ files: __dirname,
+ services: {
+ '/service': ThriftTestSvcOpt
+ }
+};
+
+const server = thrift.createWebServer(ThriftWebServerOptions);
+const port = es6Mode ? 8088 : 8089;
+server.listen(port);
+console.log(`Serving files from: ${__dirname}`);
+console.log(`Http/Thrift Server (ES6 mode ${es6Mode}) running on port: ${port}`);
diff --git a/lib/ts/test/test-int64.html b/lib/ts/test/test-int64.html
new file mode 100644
index 0000000..75ac278
--- /dev/null
+++ b/lib/ts/test/test-int64.html
@@ -0,0 +1,46 @@
++<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+ 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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Int64 Constants in JS: Unit Test</title>
+
+ <!-- QUnit Test framework-->
+ <script type="text/javascript" src="build/js/lib/qunit.js" charset="utf-8"></script>
+ <link rel="stylesheet" href="build/js/lib/qunit.css" type="text/css" media="screen" />
+
+ <!-- the Test Suite-->
+ <script type="text/javascript" src="build/ts/lib/test-int64.js" charset="utf-8"></script>
+ </head>
+<body>
+ <h1 id="qunit-header">Int64 Constants in JS: Unit Test</h1>
+ <h2 id="qunit-banner"></h2>
+ <div id="qunit-testrunner-toolbar"></div>
+ <h2 id="qunit-userAgent"></h2>
+ <ol id="qunit-tests"><li><!-- get valid xhtml strict--></li></ol>
+ <!-- Uncomment this to check the validity. This significantly slows down the test.
+ <p>
+ <a href="http://validator.w3.org/check/referer"><img
+ src="http://www.w3.org/Icons/valid-xhtml10"
+ alt="Valid XHTML 1.0!" height="31" width="88" /></a>
+ </p>
+ -->
+</body>
+</html>
diff --git a/lib/ts/test/test-int64.ts b/lib/ts/test/test-int64.ts
new file mode 100644
index 0000000..254d8d7
--- /dev/null
+++ b/lib/ts/test/test-int64.ts
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+ /* jshint -W100 */
+
+var Int64 = require("node-int64");
+var JSONInt64 = require("json-int64");
+import { Int64Test } from "./gen-js/Int64Test_types";
+
+
+// Work around for old API used by QUnitAdapter of jsTestDriver
+if (typeof QUnit.log == 'function') {
+ // When using real QUnit (fron PhantomJS) log failures to console
+ QUnit.log(function(details) {
+ if (!details.result) {
+ console.log('======== FAIL ========');
+ console.log('TestName: ' + details.name);
+ if (details.message) console.log(details.message);
+ console.log('Expected: ' + details.expected);
+ console.log('Actual : ' + details.actual);
+ console.log('======================');
+ }
+ });
+}
+
+QUnit.module('Int64');
+
+ QUnit.test('Int64', function(assert) {
+ console.log('Int64 test -- starts');
+ const EXPECTED_SMALL_INT64_AS_NUMBER: number = 42;
+ const EXPECTED_SMALL_INT64: typeof Int64 = new Int64(42);
+ const EXPECTED_MAX_JS_SAFE_INT64: typeof Int64 = new Int64(Number.MAX_SAFE_INTEGER);
+ const EXPECTED_MIN_JS_SAFE_INT64: typeof Int64 = new Int64(Number.MIN_SAFE_INTEGER);
+ const EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64: typeof Int64 = new Int64("0020000000000000"); // hex-encoded
+ const EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64: typeof Int64 = new Int64("ffe0000000000000"); // hex-encoded 2's complement
+ const EXPECTED_MAX_SIGNED_INT64: typeof Int64 = new Int64("7fffffffffffffff"); // hex-encoded
+ const EXPECTED_MIN_SIGNED_INT64: typeof Int64 = new Int64("8000000000000000"); // hex-encoded 2's complement
+ const EXPECTED_INT64_LIST = [
+ EXPECTED_SMALL_INT64,
+ EXPECTED_MAX_JS_SAFE_INT64,
+ EXPECTED_MIN_JS_SAFE_INT64,
+ EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64,
+ EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64,
+ EXPECTED_MAX_SIGNED_INT64,
+ EXPECTED_MIN_SIGNED_INT64
+ ];
+ assert.ok(EXPECTED_SMALL_INT64.equals(Int64Test.SMALL_INT64));
+ assert.ok(EXPECTED_MAX_JS_SAFE_INT64.equals(Int64Test.MAX_JS_SAFE_INT64));
+ assert.ok(EXPECTED_MIN_JS_SAFE_INT64.equals(Int64Test.MIN_JS_SAFE_INT64));
+ assert.ok(
+ EXPECTED_MAX_JS_SAFE_PLUS_ONE_INT64.equals(
+ Int64Test.MAX_JS_SAFE_PLUS_ONE_INT64
+ )
+ );
+ assert.ok(
+ EXPECTED_MIN_JS_SAFE_MINUS_ONE_INT64.equals(
+ Int64Test.MIN_JS_SAFE_MINUS_ONE_INT64
+ )
+ );
+ assert.ok(EXPECTED_MAX_SIGNED_INT64.equals(Int64Test.MAX_SIGNED_INT64));
+ assert.ok(EXPECTED_MIN_SIGNED_INT64.equals(Int64Test.MIN_SIGNED_INT64));
+ assert.equal(
+ EXPECTED_SMALL_INT64_AS_NUMBER,
+ Int64Test.SMALL_INT64.toNumber()
+ );
+ assert.equal(
+ Number.MAX_SAFE_INTEGER,
+ Int64Test.MAX_JS_SAFE_INT64.toNumber()
+ );
+ assert.equal(
+ Number.MIN_SAFE_INTEGER,
+ Int64Test.MIN_JS_SAFE_INT64.toNumber()
+ );
+
+ for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i) {
+ assert.ok(EXPECTED_INT64_LIST[i].equals(Int64Test.INT64_LIST[i]));
+ }
+
+ for (let i = 0; i < EXPECTED_INT64_LIST.length; ++i){
+ let int64Object = EXPECTED_INT64_LIST[i];
+ assert.ok(Int64Test.INT64_2_INT64_MAP[JSONInt64.toDecimalString(int64Object)].equals(int64Object));
+ }
+
+ console.log('Int64 test -- ends');
+ });
+
diff --git a/lib/ts/test/test.html b/lib/ts/test/test.html
new file mode 100755
index 0000000..ec7d7eb
--- /dev/null
+++ b/lib/ts/test/test.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+ 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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Thrift Javascript Bindings: Unit Test</title>
+
+ <script src="build/js/lib/Int64.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/js/lib/Int64Util.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/js/lib/JSONInt64.js" type="text/javascript" charset="utf-8"></script>
+ <script src="build/ts/thrift.js" type="text/javascript" charset="utf-8"></script>
+ <script src="gen-js/ThriftTest_types.js" type="text/javascript" charset="utf-8"></script>
+ <script src="gen-js/ThriftTest.js" type="text/javascript" charset="utf-8"></script>
+
+ <!-- QUnit Test framework-->
+ <!-- <script type="text/javascript" src="build/js/lib/qunit.js" charset="utf-8"></script> -->
+ <link rel="stylesheet" href="build/js/lib/qunit.css" type="text/css" media="screen" />
+
+ <!-- the Test Suite-->
+ <script type="text/javascript" src="build/ts/lib/test.js" charset="utf-8"></script>
+</head>
+<body>
+ <h1 id="qunit-header">Thrift Javascript Bindings: Unit Test (<a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=test/ThriftTest.thrift;hb=HEAD">ThriftTest.thrift</a>)</h1>
+ <h2 id="qunit-banner"></h2>
+ <div id="qunit-testrunner-toolbar"></div>
+ <h2 id="qunit-userAgent"></h2>
+ <ol id="qunit-tests"><li><!-- get valid xhtml strict--></li></ol>
+ <!-- Uncomment this to check the validity. This significantly slows down the test.
+ <p>
+ <a href="http://validator.w3.org/check/referer"><img
+ src="http://www.w3.org/Icons/valid-xhtml10"
+ alt="Valid XHTML 1.0!" height="31" width="88" /></a>
+ </p>
+ -->
+</body>
+</html>
diff --git a/lib/ts/test/test.ts b/lib/ts/test/test.ts
new file mode 100644
index 0000000..31fdcbf
--- /dev/null
+++ b/lib/ts/test/test.ts
@@ -0,0 +1,342 @@
+import { ThriftTest } from "./gen-js/ThriftTest_types";
+import "./gen-js/ThriftTest";
+
+var Int64 = require("node-int64");
+var JSONInt64 = require("json-int64");
+var QUnit = require("./qunit");
+
+const transport: Thrift.Transport = new Thrift.Transport("/service");
+const protocol: Thrift.Protocol = new Thrift.Protocol(transport);
+const client: ThriftTest.ThriftTestClient = new ThriftTest.ThriftTestClient(protocol);
+
+const int64_2_pow_60: typeof Int64 = new Int64('1000000000000000');
+const int64_minus_2_pow_60: typeof Int64 = new Int64('f000000000000000');
+
+// Work around for old API used by QUnitAdapter of jsTestDriver
+if (typeof QUnit.log == 'function') {
+ // When using real QUnit (fron PhantomJS) log failures to console
+ QUnit.log(function(details) {
+ if (!details.result) {
+ console.log('======== FAIL ========');
+ console.log('TestName: ' + details.name);
+ if (details.message) console.log(details.message);
+ console.log('Expected: ' + JSONInt64.stringify(details.expected));
+ console.log('Actual : ' + JSONInt64.stringify(details.actual));
+ console.log('======================');
+ }
+ });
+}
+
+// all Languages in UTF-8
+const stringTest: string = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski, Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia, Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa, ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар, Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, Bahasa Melayu, مازِرونی, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, Norsk (nynorsk), Norsk (bokmål), Nouormand, Diné bizaad, Occitan, Иронау, Papiamentu, Deitsch, Norfuk / Pitkern, Polski, پنجابی, پښتو, Português, Runa Simi, Rumantsch, Romani, Română, Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk, Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog, Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, Bân-lâm-gú, 粵語";
+
+
+function checkRecursively(assert, map1: Object, map2: Object): void {
+ if (typeof map1 !== 'function' && typeof map2 !== 'function') {
+ if (!map1 || typeof map1 !== 'object') {
+ assert.equal(map1, map2);
+ } else {
+ for (let key in map1) {
+ checkRecursively(assert, map1[key], map2[key]);
+ }
+ }
+ }
+}
+
+
+QUnit.module('Base Types');
+
+ QUnit.test('Void', function(assert) {
+ assert.equal(client.testVoid(), undefined);
+ });
+ QUnit.test('Binary (String)', function(assert) {
+ let binary: string = '';
+ for (let v = 255; v >= 0; --v) {
+ binary += String.fromCharCode(v);
+ }
+ assert.equal(client.testBinary(binary), binary);
+ });
+ QUnit.test('Binary (Uint8Array)', function(assert) {
+ let binary: string = '';
+ for (let v = 255; v >= 0; --v) {
+ binary += String.fromCharCode(v);
+ }
+ const arr: Uint8Array = new Uint8Array(binary.length);
+ for (let i = 0; i < binary.length; ++i) {
+ arr[i] = binary[i].charCodeAt(0);
+ }
+ const hexEncodedString = Array.from(arr, function(byte) {
+ return String.fromCharCode(byte);
+ }).join('')
+ assert.equal(client.testBinary(hexEncodedString), binary);
+ });
+ QUnit.test('String', function(assert) {
+ assert.equal(client.testString(''), '');
+ assert.equal(client.testString(stringTest), stringTest);
+
+ const specialCharacters: string = 'quote: \" backslash:' +
+ ' forwardslash-escaped: \/ ' +
+ ' backspace: \b formfeed: \f newline: \n return: \r tab: ' +
+ ' now-all-of-them-together: "\\\/\b\n\r\t' +
+ ' now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><';
+ assert.equal(client.testString(specialCharacters), specialCharacters);
+ });
+ QUnit.test('Double', function(assert) {
+ assert.equal(client.testDouble(0), 0);
+ assert.equal(client.testDouble(-1), -1);
+ assert.equal(client.testDouble(3.14), 3.14);
+ assert.equal(client.testDouble(Math.pow(2, 60)), Math.pow(2, 60));
+ });
+ QUnit.test('Byte', function(assert) {
+ assert.equal(client.testByte(0), 0);
+ assert.equal(client.testByte(0x01), 0x01);
+ });
+ QUnit.test('I32', function(assert) {
+ assert.equal(client.testI32(0), 0);
+ assert.equal(client.testI32(Math.pow(2, 30)), Math.pow(2, 30));
+ assert.equal(client.testI32(-Math.pow(2, 30)), -Math.pow(2, 30));
+ });
+ QUnit.test('I64', function(assert) {
+ assert.equal(client.testI64(new Int64(0)), 0);
+
+ let int64_2_pow_60_result: typeof Int64 = client.testI64(int64_2_pow_60);
+ assert.ok(int64_2_pow_60.equals(int64_2_pow_60_result));
+
+ let int64_minus_2_pow_60_result: typeof Int64 = client.testI64(int64_minus_2_pow_60);
+ assert.ok(int64_minus_2_pow_60.equals(int64_minus_2_pow_60_result));
+ });
+
+
+QUnit.module('Structured Types');
+
+ QUnit.test('Struct', function(assert) {
+ const structTestInput: ThriftTest.Xtruct = new ThriftTest.Xtruct();
+ structTestInput.string_thing = 'worked';
+ structTestInput.byte_thing = 0x01;
+ structTestInput.i32_thing = Math.pow(2, 30);
+ structTestInput.i64_thing = int64_2_pow_60;
+
+ const structTestOutput: ThriftTest.Xtruct = client.testStruct(structTestInput);
+
+ assert.equal(structTestOutput.string_thing, structTestInput.string_thing);
+ assert.equal(structTestOutput.byte_thing, structTestInput.byte_thing);
+ assert.equal(structTestOutput.i32_thing, structTestInput.i32_thing);
+ assert.ok(structTestOutput.i64_thing.equals(structTestInput.i64_thing));
+ assert.ok(structTestInput.i64_thing.equals(structTestOutput.i64_thing));
+
+ assert.equal(JSONInt64.stringify(structTestOutput), JSONInt64.stringify(structTestInput));
+ });
+
+ QUnit.test('Nest', function(assert) {
+ const xtrTestInput: ThriftTest.Xtruct = new ThriftTest.Xtruct();
+ xtrTestInput.string_thing = 'worked';
+ xtrTestInput.byte_thing = 0x01;
+ xtrTestInput.i32_thing = Math.pow(2, 30);
+ xtrTestInput.i64_thing = int64_2_pow_60;
+
+ const nestTestInput: ThriftTest.Xtruct2 = new ThriftTest.Xtruct2();
+ nestTestInput.byte_thing = 0x02;
+ nestTestInput.struct_thing = xtrTestInput;
+ nestTestInput.i32_thing = Math.pow(2, 15);
+
+ const nestTestOutput: ThriftTest.Xtruct2 = client.testNest(nestTestInput);
+
+ assert.equal(nestTestOutput.byte_thing, nestTestInput.byte_thing);
+ assert.equal(nestTestOutput.struct_thing.string_thing, nestTestInput.struct_thing.string_thing);
+ assert.equal(nestTestOutput.struct_thing.byte_thing, nestTestInput.struct_thing.byte_thing);
+ assert.equal(nestTestOutput.struct_thing.i32_thing, nestTestInput.struct_thing.i32_thing);
+ assert.ok(nestTestOutput.struct_thing.i64_thing.equals(nestTestInput.struct_thing.i64_thing));
+ assert.equal(nestTestOutput.i32_thing, nestTestInput.i32_thing);
+
+ assert.equal(JSONInt64.stringify(nestTestOutput), JSONInt64.stringify(nestTestInput));
+ });
+
+ QUnit.test('Map', function(assert) {
+ const mapTestInput: {[k: number]: number;} = {7: 77, 8: 88, 9: 99};
+
+ const mapTestOutput: {[k: number]: number;} = client.testMap(mapTestInput);
+
+ for (let key in mapTestOutput) {
+ assert.equal(mapTestOutput[key], mapTestInput[key]);
+ }
+ });
+
+ QUnit.test('StringMap', function(assert) {
+ const mapTestInput: {[k: string]: string;} = {
+ 'a': '123', 'a b': 'with spaces ', 'same': 'same', '0': 'numeric key',
+ 'longValue': stringTest, stringTest: 'long key'
+ };
+
+ const mapTestOutput: {[k: string]: string;} = client.testStringMap(mapTestInput);
+
+ for (let key in mapTestOutput) {
+ assert.equal(mapTestOutput[key], mapTestInput[key]);
+ }
+ });
+
+ QUnit.test('Set', function(assert) {
+ const setTestInput: number[] = [1, 2, 3];
+ assert.ok(client.testSet(setTestInput), setTestInput);
+ });
+
+ QUnit.test('List', function(assert) {
+ const listTestInput: number[] = [1, 2, 3];
+ assert.ok(client.testList(listTestInput), listTestInput);
+ });
+
+ QUnit.test('Enum', function(assert) {
+ assert.equal(client.testEnum(ThriftTest.Numberz.ONE), ThriftTest.Numberz.ONE);
+ });
+
+ QUnit.test('TypeDef', function(assert) {
+ assert.equal(client.testTypedef(new Int64(69)), 69);
+ });
+
+
+QUnit.module('deeper!');
+
+ QUnit.test('MapMap', function(assert) {
+ const mapMapTestExpectedResult: {[K: number]: {[k: number]: number}} = {
+ '4': {'1': 1, '2': 2, '3': 3, '4': 4},
+ '-4': {'-4': -4, '-3': -3, '-2': -2, '-1': -1}
+ };
+
+ const mapMapTestOutput = client.testMapMap(1);
+
+
+ for (let key in mapMapTestOutput) {
+ for (let key2 in mapMapTestOutput[key]) {
+ assert.equal(mapMapTestOutput[key][key2], mapMapTestExpectedResult[key][key2]);
+ }
+ }
+
+ checkRecursively(assert, mapMapTestOutput, mapMapTestExpectedResult);
+ });
+
+
+QUnit.module('Exception');
+
+ QUnit.test('Xception', function(assert) {
+ assert.expect(2);
+ const done = assert.async();
+ try {
+ client.testException('Xception');
+ assert.ok(false);
+ }catch (e) {
+ assert.equal(e.errorCode, 1001);
+ assert.equal(e.message, 'Xception');
+ done();
+ }
+ });
+
+ QUnit.test('no Exception', function(assert) {
+ assert.expect(1);
+ try {
+ client.testException('no Exception');
+ assert.ok(true);
+ }catch (e) {
+ assert.ok(false);
+ }
+ });
+
+ QUnit.test('TException', function(assert) {
+ //ThriftTest does not list TException as a legal exception so it will
+ // generate an exception on the server that does not propagate back to
+ // the client. This test has been modified to equate to "no exception"
+ assert.expect(1);
+ try {
+ client.testException('TException');
+ } catch (e) {
+ //assert.ok(false);
+ }
+ assert.ok(true);
+ });
+
+
+QUnit.module('Insanity');
+
+ const crazy: ThriftTest.Insanity = {
+ 'userMap': { '5': new Int64(5), '8': new Int64(8) },
+ 'xtructs': [{
+ 'string_thing': 'Goodbye4',
+ 'byte_thing': 4,
+ 'i32_thing': 4,
+ 'i64_thing': new Int64(4)
+ },
+ {
+ 'string_thing': 'Hello2',
+ 'byte_thing': 2,
+ 'i32_thing': 2,
+ 'i64_thing': new Int64(2)
+ }]
+ };
+ QUnit.test('testInsanity', function(assert) {
+ const insanity: {[k: number]: (ThriftTest.Insanity | {[k:number]: ThriftTest.Insanity})} = {
+ '1': {
+ '2': crazy,
+ '3': crazy
+ },
+ '2': { '6': new ThriftTest.Insanity() }
+ };
+ const res = client.testInsanity(new ThriftTest.Insanity(crazy));
+ assert.ok(res, JSONInt64.stringify(res));
+ assert.ok(insanity, JSONInt64.stringify(insanity));
+
+ checkRecursively(assert, res, insanity);
+ });
+
+
+//////////////////////////////////
+//Run same tests asynchronously
+
+QUnit.module('Async');
+
+ QUnit.test('Double', function(assert) {
+ assert.expect(1);
+
+ const done = assert.async();
+ client.testDouble(3.14159265, function(result) {
+ assert.equal(result, 3.14159265);
+ done();
+ });
+ });
+
+ QUnit.test('Byte', function(assert) {
+ assert.expect(1);
+
+ const done = assert.async();
+ client.testByte(0x01, function(result) {
+ assert.equal(result, 0x01);
+ done();
+ });
+ });
+
+ QUnit.test('I32', function(assert) {
+ assert.expect(2);
+
+ const done = assert.async(2);
+ client.testI32(Math.pow(2, 30), function(result) {
+ assert.equal(result, Math.pow(2, 30));
+ done();
+ });
+
+ client.testI32(Math.pow(-2, 31), function(result) {
+ assert.equal(result, Math.pow(-2, 31));
+ done();
+ });
+ });
+
+ QUnit.test('I64', function(assert) {
+ assert.expect(2);
+
+ const done = assert.async(2);
+ client.testI64(int64_2_pow_60, function(result) {
+ assert.ok(int64_2_pow_60.equals(result));
+ done();
+ });
+
+ client.testI64(int64_minus_2_pow_60, function(result) {
+ assert.ok(int64_minus_2_pow_60.equals(result));
+ done();
+ });
+ });
diff --git a/lib/ts/test/test_handler.js b/lib/ts/test/test_handler.js
new file mode 100644
index 0000000..8ba296b
--- /dev/null
+++ b/lib/ts/test/test_handler.js
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+//This is the server side Node test handler for the standard
+// Apache Thrift test service.
+
+const es6Mode = process.argv.includes('--es6');
+const genFolder = es6Mode ? 'gen-nodejs-es6' : 'gen-nodejs';
+const ttypes = require(`./${genFolder}/ThriftTest_types`);
+const TException = require('../../nodejs/lib/thrift').TException;
+const Int64 = require('node-int64');
+
+exports.ThriftTestHandler = {
+ testVoid: function(result) {
+ console.log('testVoid()');
+ result(null);
+ },
+ testString: function(thing, result) {
+ console.log('testString(\'' + thing + '\')');
+ result(null, thing);
+ },
+ testByte: function(thing, result) {
+ console.log('testByte(' + thing + ')');
+ result(null, thing);
+ },
+ testI32: function(thing, result) {
+ console.log('testI32(' + thing + ')');
+ result(null, thing);
+ },
+ testI64: function(thing, result) {
+ console.log('testI64(' + thing + ')');
+ result(null, thing);
+ },
+ testDouble: function(thing, result) {
+ console.log('testDouble(' + thing + ')');
+ result(null, thing);
+ },
+ testBinary: function(thing, result) {
+ console.log('testBinary(\'' + thing + '\')');
+ result(null, thing);
+ },
+ testStruct: function(thing, result) {
+ console.log('testStruct(');
+ console.log(thing);
+ console.log(')');
+ result(null, thing);
+ },
+ testNest: function(nest, result) {
+ console.log('testNest(');
+ console.log(nest);
+ console.log(')');
+ result(null, nest);
+ },
+ testMap: function(thing, result) {
+ console.log('testMap(');
+ console.log(thing);
+ console.log(')');
+ result(null, thing);
+ },
+ testStringMap: function(thing, result) {
+ console.log('testStringMap(');
+ console.log(thing);
+ console.log(')');
+ result(null, thing);
+ },
+ testSet: function(thing, result) {
+ console.log('testSet(');
+ console.log(thing);
+ console.log(')');
+ result(null, thing);
+ },
+ testList: function(thing, result) {
+ console.log('testList(');
+ console.log(thing);
+ console.log(')');
+ result(null, thing);
+ },
+ testEnum: function(thing, result) {
+ console.log('testEnum(' + thing + ')');
+ result(null, thing);
+ },
+ testTypedef: function(thing, result) {
+ console.log('testTypedef(' + thing + ')');
+ result(null, thing);
+ },
+ testMapMap: function(hello, result) {
+ console.log('testMapMap(' + hello + ')');
+
+ const mapmap = [];
+ const pos = [];
+ const neg = [];
+ for (let i = 1; i < 5; i++) {
+ pos[i] = i;
+ neg[-i] = -i;
+ }
+ mapmap[4] = pos;
+ mapmap[-4] = neg;
+
+ result(null, mapmap);
+ },
+ testInsanity: function(argument, result) {
+ console.log('testInsanity(');
+ console.log(argument);
+ console.log(')');
+
+ const hello = new ttypes.Xtruct();
+ hello.string_thing = 'Hello2';
+ hello.byte_thing = 2;
+ hello.i32_thing = 2;
+ hello.i64_thing = new Int64(2);
+
+ const goodbye = new ttypes.Xtruct();
+ goodbye.string_thing = 'Goodbye4';
+ goodbye.byte_thing = 4;
+ goodbye.i32_thing = 4;
+ goodbye.i64_thing = new Int64(4);
+
+ const crazy = new ttypes.Insanity();
+ crazy.userMap = [];
+ crazy.userMap[ttypes.Numberz.EIGHT] = 8;
+ crazy.userMap[ttypes.Numberz.FIVE] = 5;
+ crazy.xtructs = [goodbye, hello];
+
+ const first_map = [];
+ const second_map = [];
+
+ first_map[ttypes.Numberz.TWO] = crazy;
+ first_map[ttypes.Numberz.THREE] = crazy;
+
+ const looney = new ttypes.Insanity();
+ second_map[ttypes.Numberz.SIX] = looney;
+
+ const insane = [];
+ insane[1] = first_map;
+ insane[2] = second_map;
+
+ console.log('insane result:');
+ console.log(insane);
+ result(null, insane);
+ },
+ testMulti: function(arg0, arg1, arg2, arg3, arg4, arg5, result) {
+ console.log('testMulti()');
+
+ const hello = new ttypes.Xtruct();
+ hello.string_thing = 'Hello2';
+ hello.byte_thing = arg0;
+ hello.i32_thing = arg1;
+ hello.i64_thing = arg2;
+ result(null, hello);
+ },
+ testException: function(arg, result) {
+ console.log('testException(' + arg + ')');
+ if (arg === 'Xception') {
+ const x = new ttypes.Xception();
+ x.errorCode = 1001;
+ x.message = arg;
+ result(x);
+ } else if (arg === 'TException') {
+ result(new TException(arg));
+ } else {
+ result(null);
+ }
+ },
+ testMultiException: function(arg0, arg1, result) {
+ console.log('testMultiException(' + arg0 + ', ' + arg1 + ')');
+ if (arg0 === ('Xception')) {
+ const x = new ttypes.Xception();
+ x.errorCode = 1001;
+ x.message = 'This is an Xception';
+ result(x);
+ } else if (arg0 === ('Xception2')) {
+ const x2 = new ttypes.Xception2();
+ x2.errorCode = 2002;
+ x2.struct_thing = new ttypes.Xtruct();
+ x2.struct_thing.string_thing = 'This is an Xception2';
+ result(x2);
+ }
+
+ const res = new ttypes.Xtruct();
+ res.string_thing = arg1;
+ result(null, res);
+ },
+ testOneway: function(sleepFor, result) {
+ console.log('testOneway(' + sleepFor + ') => JavaScript (like Rust) never sleeps!');
+ }
+}; //ThriftTestSvcHandler
diff --git a/lib/ts/tsconfig.json b/lib/ts/tsconfig.json
new file mode 100644
index 0000000..97fa225
--- /dev/null
+++ b/lib/ts/tsconfig.json
@@ -0,0 +1,31 @@
+{
+ "compilerOptions": {
+ "allowJs": false,
+ "alwaysStrict": true,
+ "baseUrl": ".",
+ "declaration": true,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "noImplicitThis": true,
+ "noUnusedLocals": true,
+ "preserveConstEnums": true,
+ "removeComments": true,
+ "strictFunctionTypes": true,
+ "strictNullChecks": true,
+ "target": "es6",
+ "paths": {
+ "*": [
+ "*",
+ "test/",
+ "test/gen-js/*"
+
+ ]
+ },
+ },
+ "exclude": [
+ "./test/gen-nodejs/",
+ "./test/build/",
+ ]
+}
diff --git a/package-lock.json b/package-lock.json
index a7e59e8..8eb8a21 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "thrift",
- "version": "0.12.1",
+ "version": "0.13.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -30,6 +30,15 @@
"integrity": "sha512-+ZWB5Ec1iki99xQFzBlivlKxSZQ+fuUKBott8StBOnLN4dWbRHlgdg1XknpW6g0tweniN5DcOqA64CJyOUPSAw==",
"dev": true
},
+ "@types/node-int64": {
+ "version": "0.4.29",
+ "resolved": "https://registry.npmjs.org/@types/node-int64/-/node-int64-0.4.29.tgz",
+ "integrity": "sha512-rHXvenLTj/CcsmNAebaBOhxQ2MqEGl3yXZZcZ21XYR+gzGTTcpOy2N4IxpvTCz48loyQNatHvfn6GhIbbZ1R3Q==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@types/q": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.1.tgz",
@@ -140,6 +149,21 @@
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
"dev": true
},
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ },
"async": {
"version": "1.5.2",
"resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
@@ -151,6 +175,24 @@
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
},
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
+ "dev": true
+ },
"babylon": {
"version": "7.0.0-beta.19",
"resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.19.tgz",
@@ -163,6 +205,15 @@
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "dev": true,
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
"bindings": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz",
@@ -238,6 +289,12 @@
"integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
"dev": true
},
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+ "dev": true
+ },
"catharsis": {
"version": "0.8.9",
"resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.9.tgz",
@@ -312,6 +369,15 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
+ "combined-stream": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
+ "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
"commander": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
@@ -361,6 +427,15 @@
"which": "^1.2.9"
}
},
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -427,6 +502,12 @@
"rimraf": "^2.2.8"
}
},
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
"delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
@@ -448,6 +529,16 @@
"esutils": "^2.0.2"
}
},
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "dev": true,
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -688,6 +779,12 @@
"integrity": "sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg==",
"dev": true
},
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true
+ },
"external-editor": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz",
@@ -699,6 +796,12 @@
"tmp": "^0.0.33"
}
},
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "dev": true
+ },
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
@@ -778,6 +881,23 @@
"is-callable": "^1.1.3"
}
},
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
@@ -861,6 +981,15 @@
"integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
"dev": true
},
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
"github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
@@ -936,6 +1065,36 @@
}
}
},
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.5.5",
+ "har-schema": "^2.0.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz",
+ "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ }
+ }
+ },
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -963,6 +1122,45 @@
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
"dev": true
},
+ "html-validator": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/html-validator/-/html-validator-3.1.3.tgz",
+ "integrity": "sha512-RhjcQIHS/SfYzQ+/JrFWKU6AVve6AuwftAG/cWX3+bpvBK/tGMqbOleKlsAxLrKD84+GSJ1oJGnkyhdVLBGCqg==",
+ "dev": true,
+ "requires": {
+ "request": "2.88.0",
+ "valid-url": "1.0.9"
+ }
+ },
+ "html-validator-cli": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/html-validator-cli/-/html-validator-cli-4.1.4.tgz",
+ "integrity": "sha512-4vGP107UDhhNHeWA5N8j/nUPlQbtB/W/K2x/P7aElbWMWrOkJA0MRSVFsMFrTPSAAjZWCG9uki2+1cQDzFtVcQ==",
+ "dev": true,
+ "requires": {
+ "html-validator": "3.1.3",
+ "minimist": "1.2.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -1099,6 +1297,12 @@
"has-symbols": "^1.0.0"
}
},
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -1111,6 +1315,12 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true
+ },
"istanbul": {
"version": "0.4.5",
"resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz",
@@ -1194,6 +1404,12 @@
"xmlcreate": "^1.0.1"
}
},
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true
+ },
"jsdoc": {
"version": "3.5.5",
"resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.5.5.tgz",
@@ -1214,6 +1430,21 @@
"underscore": "~1.8.3"
}
},
+ "json-int64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-int64/-/json-int64-1.0.0.tgz",
+ "integrity": "sha512-yrTg9swToElhEPETLMdZkEzDhbXLs+cxkw/b2rglMPOBlM1DE0utH1EReSMLcnpYJk5iUvD12r0fP2/xHitF5Q==",
+ "dev": true,
+ "requires": {
+ "node-int64": "0.4.0"
+ }
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true
+ },
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -1226,6 +1457,24 @@
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
"klaw": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/klaw/-/klaw-2.0.0.tgz",
@@ -1257,6 +1506,21 @@
"integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
"dev": true
},
+ "mime-db": {
+ "version": "1.37.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
+ "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.21",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
+ "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
+ "dev": true,
+ "requires": {
+ "mime-db": "~1.37.0"
+ }
+ },
"mimic-fn": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
@@ -1370,6 +1634,12 @@
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true
},
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "dev": true
+ },
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -1489,6 +1759,12 @@
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true
},
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+ "dev": true
+ },
"pify": {
"version": "2.3.0",
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
@@ -1580,6 +1856,12 @@
"integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==",
"dev": true
},
+ "psl": {
+ "version": "1.1.31",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
+ "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==",
+ "dev": true
+ },
"pump": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
@@ -1601,6 +1883,12 @@
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
},
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+ "dev": true
+ },
"rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -1642,6 +1930,34 @@
"integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
"dev": true
},
+ "request": {
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.0",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.4.3",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
"require-uncached": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
@@ -1814,6 +2130,23 @@
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
},
+ "sshpk": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+ "dev": true,
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
"statuses": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
@@ -1996,6 +2329,24 @@
"integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
"dev": true
},
+ "tough-cookie": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+ "dev": true,
+ "requires": {
+ "psl": "^1.1.24",
+ "punycode": "^1.4.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ }
+ }
+ },
"tslib": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
@@ -2011,6 +2362,12 @@
"safe-buffer": "^5.0.1"
}
},
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true
+ },
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
@@ -2114,6 +2471,29 @@
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
"dev": true
},
+ "uuid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+ "dev": true
+ },
+ "valid-url": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
+ "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=",
+ "dev": true
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
diff --git a/package.json b/package.json
index b7a4947..6393ee7 100644
--- a/package.json
+++ b/package.json
@@ -4,9 +4,9 @@
"homepage": "http://thrift.apache.org/",
"repository": {
"type": "git",
- "url": "https://git-wip-us.apache.org/repos/asf/thrift.git"
+ "url": "https://github.com/apache/thrift.git"
},
- "version": "0.12.1",
+ "version": "0.13.0",
"author": {
"name": "Apache Thrift Developers",
"email": "dev@thrift.apache.org",
@@ -30,6 +30,7 @@
"directories": {
"lib": "./lib/nodejs/lib/thrift"
},
+ "browser": "./lib/nodejs/lib/thrift/browser.js",
"main": "./lib/nodejs/lib/thrift",
"engines": {
"node": ">= 4.1.0"
@@ -46,13 +47,16 @@
"eslint": "^5.7.0",
"eslint-config-prettier": "^3.1.0",
"eslint-plugin-prettier": "^3.0.0",
+ "html-validator-cli": "^4.1.4",
"istanbul": "^0.4.5",
"jsdoc": "^3.5.5",
+ "json-int64": "^1.0.0",
"prettier": "^1.14.3",
"tape": "^4.9.0",
"utf-8-validate": "^4.0.0",
"typescript": "^3.1.6",
"@types/node": "^10.12.6",
+ "@types/node-int64": "^0.4.29",
"@types/q": "^1.5.1"
},
"scripts": {
diff --git a/pull_request_template.md b/pull_request_template.md
deleted file mode 100644
index 0b6965b..0000000
--- a/pull_request_template.md
+++ /dev/null
@@ -1,19 +0,0 @@
-Some helpful tips for a successful Apache Thrift PR:
-
-* Did you test your changes locally or using CI in your fork?
-* Is the Apache Jira THRIFT ticket identifier in the PR title?
-* Is the Apache Jira THRIFT ticket identifier in the commit message?
-* Did you squash your changes to a single commit?
-* Are these changes backwards compatible? (please say so in PR description)
-* Do you need to update the language-specific README?
-
-Example ideal pull request title:
-
- THRIFT-9999: an example pull request title
-
-Example ideal commit message:
-
- THRIFT-9999: [summary of fix, one line if possible]
- Client: [language(s) affected, comma separated, use lib/ directory names please]
-
-For more information about committing, see CONTRIBUTING.md
diff --git a/sonar-project.properties b/sonar-project.properties
index e8fcda8..a238197 100755
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -16,7 +16,7 @@
services that work efficiently and seamlessly between all major languages.
# Apache Thrift Version
-sonar.projectVersion=0.12.1
+sonar.projectVersion=0.13.0
# use this to set another version string
# $ sonar-runner -D sonar.projectVersion=`git rev-parse HEAD`
# set projectDate in combination with projectVersion for imports of old releases
@@ -31,7 +31,7 @@
sonar.sourceEncoding=UTF-8
# scm
-sonar.scm.url=scm:git:https://git-wip-us.apache.org/repos/asf/thrift
+sonar.scm.url=scm:git:https://github.com/apache/thrift.git
# cppcheck -q --error-exitcode=0 --xml . 2> cppcheck-result.xml
sonar.cxx.cppcheck.reportPath=cppcheck-result.xml
@@ -54,7 +54,7 @@
module1.sonar.projectBaseDir=lib/java
module1.sonar.sources=src
module1.sonar.tests=test
-module1.sonar.binaries=build/libs/libthrift-0.12.1.jar
+module1.sonar.binaries=build/libs/libthrift-0.13.0.jar
module1.sonar.libraries=build/deps/*.jar
module1.sonar.language=java
@@ -62,7 +62,7 @@
module2.sonar.projectBaseDir=.
module2.sonar.sources=tutorial/java/src, tutorial/java/gen-java
module2.sonar.binaries=tutorial/java/tutorial.jar
-module2.sonar.libraries=lib/java/build/deps/*.jar,lib/java/build/libs/libthrift-0.12.1.jar
+module2.sonar.libraries=lib/java/build/deps/*.jar,lib/java/build/libs/libthrift-0.13.0.jar
module2.sonar.language=java
module3.sonar.projectName=Apache Thrift - JavaScript Library
diff --git a/test/Int64Test.thrift b/test/Int64Test.thrift
new file mode 100644
index 0000000..348cc9c
--- /dev/null
+++ b/test/Int64Test.thrift
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+namespace js Int64Test
+
+const i64 SMALL_INT64 = 42
+const i64 MAX_JS_SAFE_INT64 = 9007199254740991
+const i64 MIN_JS_SAFE_INT64 = -9007199254740991
+const i64 MAX_JS_SAFE_PLUS_ONE_INT64 = 9007199254740992
+const i64 MIN_JS_SAFE_MINUS_ONE_INT64 = -9007199254740992
+const i64 MAX_SIGNED_INT64 = 9223372036854775807
+const i64 MIN_SIGNED_INT64 = -9223372036854775808
+
+const list<i64> INT64_LIST = [SMALL_INT64, MAX_JS_SAFE_INT64, MIN_JS_SAFE_INT64, MAX_JS_SAFE_PLUS_ONE_INT64, MIN_JS_SAFE_MINUS_ONE_INT64, MAX_SIGNED_INT64, MIN_SIGNED_INT64]
+
+const map<i64, i64> INT64_2_INT64_MAP = {
+ SMALL_INT64: SMALL_INT64,
+ MAX_JS_SAFE_INT64: MAX_JS_SAFE_INT64,
+ MIN_JS_SAFE_INT64: MIN_JS_SAFE_INT64,
+ MAX_JS_SAFE_PLUS_ONE_INT64: MAX_JS_SAFE_PLUS_ONE_INT64,
+ MIN_JS_SAFE_MINUS_ONE_INT64: MIN_JS_SAFE_MINUS_ONE_INT64,
+ MAX_SIGNED_INT64: MAX_SIGNED_INT64,
+ MIN_SIGNED_INT64: MIN_SIGNED_INT64
+ }
diff --git a/test/Makefile.am b/test/Makefile.am
index 68f1986..f6b867c 100755
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -77,8 +77,9 @@
SUBDIRS += haxe
endif
-if WITH_DOTNETCORE
+if WITH_DOTNET
SUBDIRS += netcore
+SUBDIRS += netstd
endif
if WITH_GO
@@ -102,31 +103,45 @@
endif
#
-# generate html for ThriftTest.thrift
+# generate html for ThriftTest.thrift AND validate it!
#
+if WITH_NODEJS
check-local:
$(top_builddir)/compiler/cpp/thrift --gen html -r $(top_srcdir)/test/ThriftTest.thrift
+ $(top_builddir)/node_modules/.bin/html-validator --file=gen-html/index.html --verbose
+ $(top_builddir)/node_modules/.bin/html-validator --file=gen-html/ThriftTest.html --verbose
+else
+check-local:
+ $(top_builddir)/compiler/cpp/thrift --gen html -r $(top_srcdir)/test/ThriftTest.thrift
+endif
clean-local:
- rm -rf $(top_srcdir)/test/gen-html
+ $(RM) -r $(top_srcdir)/test/gen-html/
+ find . -type d -name "__pycache__" | xargs rm -rf
+ find . -type f -name "*.pyc" | xargs rm -f
+
+dist-hook:
+ $(RM) -r $(distdir)/gen-html/
+ find $(distdir) -type d -name "__pycache__" | xargs rm -rf
+ find $(distdir) -type f -name "*.pyc" | xargs rm -f
EXTRA_DIST = \
audit \
- crossrunner \
- keys \
c_glib \
cl \
cpp \
+ crossrunner \
dart \
erl \
hs \
+ keys \
lua \
ocaml \
perl \
php \
py \
- py.twisted \
py.tornado \
+ py.twisted \
rb \
rs \
threads \
@@ -134,12 +149,14 @@
BrokenConstants.thrift \
ConstantsDemo.thrift \
DebugProtoTest.thrift \
- DoubleConstantsTest.thrift \
DenseLinkingTest.thrift \
DocTest.thrift \
+ DoubleConstantsTest.thrift \
+ EnumContainersTest.thrift \
EnumTest.thrift \
FullCamelTest.thrift \
Include.thrift \
+ Int64Test.thrift \
JavaBeansTest.thrift \
JavaDeepCopyTest.thrift \
JavaTypes.thrift \
@@ -150,7 +167,6 @@
OptionalRequiredTest.thrift \
Recursive.thrift \
ReuseObjects.thrift \
- EnumContainersTest.thrift \
SmallTest.thrift \
StressTest.thrift \
ThriftTest.thrift \
diff --git a/test/ThriftTest.thrift b/test/ThriftTest.thrift
index 3499ab5..d1e6b5e 100644
--- a/test/ThriftTest.thrift
+++ b/test/ThriftTest.thrift
@@ -22,22 +22,22 @@
*/
namespace c_glib TTest
-namespace java thrift.test
namespace cpp thrift.test
-namespace rb Thrift.Test
-namespace perl ThriftTest
namespace csharp Thrift.Test
+namespace delphi Thrift.Test
+namespace go thrifttest
+namespace java thrift.test
namespace js ThriftTest
-namespace st ThriftTest
+namespace lua ThriftTest
+namespace netcore ThriftTest
+namespace netstd ThriftTest
+namespace perl ThriftTest
+namespace php ThriftTest
namespace py ThriftTest
namespace py.twisted ThriftTest
-namespace go thrifttest
-namespace php ThriftTest
-namespace delphi Thrift.Test
-namespace cocoa ThriftTest
-namespace lua ThriftTest
+namespace rb Thrift.Test
+namespace st ThriftTest
namespace xsd test (uri = 'http://thrift.apache.org/ns/ThriftTest')
-namespace netcore ThriftTest
// Presence of namespaces and sub-namespaces for which there is
// no generator should compile with warnings only
diff --git a/test/c_glib/CMakeLists.txt b/test/c_glib/CMakeLists.txt
new file mode 100644
index 0000000..9817315
--- /dev/null
+++ b/test/c_glib/CMakeLists.txt
@@ -0,0 +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.
+#
+
+# Contains the thrift specific LINK_AGAINST_THRIFT_LIBRARY
+include(ThriftMacros)
+
+find_package(GLIB REQUIRED COMPONENTS gobject)
+include_directories(SYSTEM "${GLIB_INCLUDE_DIR}")
+include_directories(SYSTEM "${GLIBCONFIG_INCLUDE_DIR}")
+
+#Make sure gen-c_glib files can be included
+include_directories("${CMAKE_CURRENT_BINARY_DIR}")
+include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-c_glib")
+include_directories("${PROJECT_SOURCE_DIR}/lib/c_glib/src")
+
+set(crosstestgencglib_SOURCES
+ gen-c_glib/t_test_second_service.c
+ gen-c_glib/t_test_second_service.h
+ gen-c_glib/t_test_thrift_test.c
+ gen-c_glib/t_test_thrift_test.h
+ gen-c_glib/t_test_thrift_test_types.c
+ gen-c_glib/t_test_thrift_test_types.h
+)
+add_library(crosstestgencglib STATIC ${crosstestgencglib_SOURCES})
+LINK_AGAINST_THRIFT_LIBRARY(crosstestgencglib thrift_c_glib)
+
+add_executable(test_server src/test_server.c src/thrift_test_handler.c src/thrift_second_service_handler.c)
+target_link_libraries(test_server crosstestgencglib)
+
+add_executable(test_client src/test_client.c)
+target_link_libraries(test_client crosstestgencglib)
+
+#
+# Common thrift code generation rules
+#
+
+add_custom_command(OUTPUT gen-c_glib/t_test_second_service.c gen-c_glib/t_test_second_service.h gen-c_glib/t_test_thrift_test.c gen-c_glib/t_test_thrift_test.h gen-c_glib/t_test_thrift_test_types.c gen-c_glib/t_test_thrift_test_types.h
+ COMMAND ${THRIFT_COMPILER} --gen c_glib -r ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
+)
diff --git a/test/c_glib/Makefile.am b/test/c_glib/Makefile.am
index 4a03d29..01ab2ca 100755
--- a/test/c_glib/Makefile.am
+++ b/test/c_glib/Makefile.am
@@ -65,10 +65,18 @@
AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) @GCOV_LDFLAGS@
clean-local:
- $(RM) gen-c_glib/*
+ $(RM) -r gen-c_glib/
+ $(RM) test_client
+ $(RM) test_server
+ $(RM) libtestcglib.la
+ find . -type f -iname "*.o" | xargs rm -f
+
+dist-hook:
+ $(RM) -r $(distdir)/gen-c_glib/
+ $(RM) $(distdir)/test_client
+ $(RM) $(distdir)/test_server
+ $(RM) $(distdir)/libtestcglib.la
+ find $(distdir) -type f -iname "*.o" | xargs rm -f
EXTRA_DIST = \
- src/test_client.c \
- src/thrift_test_handler.c \
- src/thrift_test_handler.h \
- src/test_server.c
+ src
diff --git a/test/cpp/CMakeLists.txt b/test/cpp/CMakeLists.txt
index 95d2991..90af782 100755
--- a/test/cpp/CMakeLists.txt
+++ b/test/cpp/CMakeLists.txt
@@ -17,11 +17,15 @@
# under the License.
#
+# The test executables still depend on Boost
+include(BoostMacros)
+REQUIRE_BOOST_HEADERS()
+set(BOOST_COMPONENTS filesystem program_options random)
+REQUIRE_BOOST_LIBRARIES(BOOST_COMPONENTS)
+
# Contains the thrift specific LINK_AGAINST_THRIFT_LIBRARY
include(ThriftMacros)
-include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
-
find_package(OpenSSL REQUIRED)
include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
@@ -71,6 +75,7 @@
LINK_AGAINST_THRIFT_LIBRARY(StressTest thrift)
LINK_AGAINST_THRIFT_LIBRARY(StressTest thriftnb)
add_test(NAME StressTest COMMAND StressTest)
+add_test(NAME StressTestConcurrent COMMAND StressTest --client-type=concurrent)
add_executable(StressTestNonBlocking src/StressTestNonBlocking.cpp)
target_link_libraries(StressTestNonBlocking crossstressgencpp ${Boost_LIBRARIES} ${LIBEVENT_LIB})
diff --git a/test/cpp/Makefile.am b/test/cpp/Makefile.am
index e8be80a..ebe715e 100755
--- a/test/cpp/Makefile.am
+++ b/test/cpp/Makefile.am
@@ -113,7 +113,7 @@
AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) $(ZLIB_LIBS)
clean-local:
- $(RM) gen-cpp/*
+ $(RM) -r gen-cpp/
style-local:
$(CPPSTYLE_CMD)
diff --git a/test/cpp/src/StressTest.cpp b/test/cpp/src/StressTest.cpp
index 5ff5e44..79a708e 100644
--- a/test/cpp/src/StressTest.cpp
+++ b/test/cpp/src/StressTest.cpp
@@ -18,9 +18,8 @@
*/
#include <thrift/concurrency/ThreadManager.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/Util.h>
#include <thrift/concurrency/Mutex.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
@@ -31,7 +30,6 @@
#include <thrift/transport/TTransportUtils.h>
#include <thrift/transport/TFileTransport.h>
#include <thrift/TLogging.h>
-#include <thrift/stdcxx.h>
#include "Service.h"
#include <iostream>
@@ -46,6 +44,7 @@
using namespace std;
using namespace apache::thrift;
+using namespace apache::thrift::async;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;
@@ -66,7 +65,7 @@
class Server : public ServiceIf {
public:
- Server() {}
+ Server() = default;
void count(const char* method) {
Guard m(lock_);
@@ -74,7 +73,7 @@
counts_[method] = ++ct;
}
- void echoVoid() {
+ void echoVoid() override {
count("echoVoid");
return;
}
@@ -84,18 +83,18 @@
return counts_;
}
- int8_t echoByte(const int8_t arg) { return arg; }
- int32_t echoI32(const int32_t arg) { return arg; }
- int64_t echoI64(const int64_t arg) { return arg; }
- void echoString(string& out, const string& arg) {
+ int8_t echoByte(const int8_t arg) override { return arg; }
+ int32_t echoI32(const int32_t arg) override { return arg; }
+ int64_t echoI64(const int64_t arg) override { return arg; }
+ void echoString(string& out, const string& arg) override {
if (arg != "hello") {
T_ERROR_ABORT("WRONG STRING (%s)!!!!", arg.c_str());
}
out = arg;
}
- void echoList(vector<int8_t>& out, const vector<int8_t>& arg) { out = arg; }
- void echoSet(set<int8_t>& out, const set<int8_t>& arg) { out = arg; }
- void echoMap(map<int8_t, int8_t>& out, const map<int8_t, int8_t>& arg) { out = arg; }
+ void echoList(vector<int8_t>& out, const vector<int8_t>& arg) override { out = arg; }
+ void echoSet(set<int8_t>& out, const set<int8_t>& arg) override { out = arg; }
+ void echoMap(map<int8_t, int8_t>& out, const map<int8_t, int8_t>& arg) override { out = arg; }
private:
count_map counts_;
@@ -108,8 +107,8 @@
};
class ClientThread : public Runnable {
public:
- ClientThread(stdcxx::shared_ptr<TTransport> transport,
- stdcxx::shared_ptr<ServiceIf> client,
+ ClientThread(std::shared_ptr<TTransport> transport,
+ std::shared_ptr<ServiceIf> client,
Monitor& monitor,
size_t& workerCount,
size_t loopCount,
@@ -123,7 +122,7 @@
_loopType(loopType),
_behavior(behavior) {}
- void run() {
+ void run() override {
// Wait for all worker threads to start
@@ -134,7 +133,7 @@
}
}
- _startTime = Util::currentTime();
+ _startTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
if(_behavior == OpenAndCloseTransportInThread) {
_transport->open();
}
@@ -160,7 +159,7 @@
break;
}
- _endTime = Util::currentTime();
+ _endTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
if(_behavior == OpenAndCloseTransportInThread) {
_transport->close();
@@ -225,8 +224,8 @@
}
}
- stdcxx::shared_ptr<TTransport> _transport;
- stdcxx::shared_ptr<ServiceIf> _client;
+ std::shared_ptr<TTransport> _transport;
+ std::shared_ptr<ServiceIf> _client;
Monitor& _monitor;
size_t& _workerCount;
size_t _loopCount;
@@ -241,7 +240,7 @@
class TStartObserver : public apache::thrift::server::TServerEventHandler {
public:
TStartObserver() : awake_(false) {}
- virtual void preServe() {
+ void preServe() override {
apache::thrift::concurrency::Synchronized s(m_);
awake_ = true;
m_.notifyAll();
@@ -266,8 +265,8 @@
string clientType = "regular";
string serverType = "thread-pool";
string protocolType = "binary";
- size_t workerCount = 4;
- size_t clientCount = 20;
+ size_t workerCount = 8;
+ size_t clientCount = 4;
size_t loopCount = 50000;
TType loopType = T_VOID;
string callName = "echoVoid";
@@ -391,24 +390,24 @@
cerr << usage.str();
}
- stdcxx::shared_ptr<PlatformThreadFactory> threadFactory
- = stdcxx::shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory());
+ std::shared_ptr<ThreadFactory> threadFactory
+ = std::shared_ptr<ThreadFactory>(new ThreadFactory());
// Dispatcher
- stdcxx::shared_ptr<Server> serviceHandler(new Server());
+ std::shared_ptr<Server> serviceHandler(new Server());
if (replayRequests) {
- stdcxx::shared_ptr<Server> serviceHandler(new Server());
- stdcxx::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
+ std::shared_ptr<Server> serviceHandler(new Server());
+ std::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
// Transports
- stdcxx::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
+ std::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
fileTransport->setChunkSize(2 * 1024 * 1024);
fileTransport->setMaxEventSize(1024 * 16);
fileTransport->seekToEnd();
// Protocol Factory
- stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
+ std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TFileProcessor fileProcessor(serviceProcessor, protocolFactory, fileTransport);
@@ -418,28 +417,28 @@
if (runServer) {
- stdcxx::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
+ std::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
// Transport
- stdcxx::shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));
+ std::shared_ptr<TServerSocket> serverSocket(new TServerSocket(port));
// Transport Factory
- stdcxx::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
+ std::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
// Protocol Factory
- stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
+ std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
if (logRequests) {
// initialize the log file
- stdcxx::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
+ std::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
fileTransport->setChunkSize(2 * 1024 * 1024);
fileTransport->setMaxEventSize(1024 * 16);
transportFactory
- = stdcxx::shared_ptr<TTransportFactory>(new TPipedTransportFactory(fileTransport));
+ = std::shared_ptr<TTransportFactory>(new TPipedTransportFactory(fileTransport));
}
- stdcxx::shared_ptr<TServer> server;
+ std::shared_ptr<TServer> server;
if (serverType == "simple") {
@@ -453,7 +452,7 @@
} else if (serverType == "thread-pool") {
- stdcxx::shared_ptr<ThreadManager> threadManager
+ std::shared_ptr<ThreadManager> threadManager
= ThreadManager::newSimpleThreadManager(workerCount);
threadManager->threadFactory(threadFactory);
@@ -465,9 +464,9 @@
threadManager));
}
- stdcxx::shared_ptr<TStartObserver> observer(new TStartObserver);
+ std::shared_ptr<TStartObserver> observer(new TStartObserver);
server->setServerEventHandler(observer);
- stdcxx::shared_ptr<Thread> serverThread = threadFactory->newThread(server);
+ std::shared_ptr<Thread> serverThread = threadFactory->newThread(server);
cerr << "Starting the server on port " << port << endl;
@@ -486,7 +485,7 @@
size_t threadCount = 0;
- set<stdcxx::shared_ptr<Thread> > clientThreads;
+ set<std::shared_ptr<Thread> > clientThreads;
if (callName == "echoVoid") {
loopType = T_VOID;
@@ -505,28 +504,28 @@
if(clientType == "regular") {
for (size_t ix = 0; ix < clientCount; ix++) {
- stdcxx::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port));
- stdcxx::shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket, 2048));
- stdcxx::shared_ptr<TProtocol> protocol(new TBinaryProtocol(bufferedSocket));
- stdcxx::shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
+ std::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port));
+ std::shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket, 2048));
+ std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(bufferedSocket));
+ std::shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
- clientThreads.insert(threadFactory->newThread(stdcxx::shared_ptr<ClientThread>(
+ clientThreads.insert(threadFactory->newThread(std::shared_ptr<ClientThread>(
new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType, OpenAndCloseTransportInThread))));
}
} else if(clientType == "concurrent") {
- stdcxx::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port));
- stdcxx::shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket, 2048));
- stdcxx::shared_ptr<TProtocol> protocol(new TBinaryProtocol(bufferedSocket));
- //stdcxx::shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
- stdcxx::shared_ptr<ServiceConcurrentClient> serviceClient(new ServiceConcurrentClient(protocol));
+ std::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port));
+ std::shared_ptr<TBufferedTransport> bufferedSocket(new TBufferedTransport(socket, 2048));
+ std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(bufferedSocket));
+ auto sync = std::make_shared<TConcurrentClientSyncInfo>();
+ std::shared_ptr<ServiceConcurrentClient> serviceClient(new ServiceConcurrentClient(protocol, sync));
socket->open();
for (size_t ix = 0; ix < clientCount; ix++) {
- clientThreads.insert(threadFactory->newThread(stdcxx::shared_ptr<ClientThread>(
+ clientThreads.insert(threadFactory->newThread(std::shared_ptr<ClientThread>(
new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType, DontOpenAndCloseTransportInThread))));
}
}
- for (std::set<stdcxx::shared_ptr<Thread> >::const_iterator thread = clientThreads.begin();
+ for (auto thread = clientThreads.begin();
thread != clientThreads.end();
thread++) {
(*thread)->start();
@@ -541,7 +540,7 @@
cerr << "Launch " << clientCount << " " << clientType << " client threads" << endl;
- time00 = Util::currentTime();
+ time00 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
monitor.notifyAll();
@@ -549,7 +548,7 @@
monitor.wait();
}
- time01 = Util::currentTime();
+ time01 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
int64_t firstTime = 9223372036854775807LL;
@@ -559,12 +558,12 @@
int64_t minTime = 9223372036854775807LL;
int64_t maxTime = 0;
- for (set<stdcxx::shared_ptr<Thread> >::iterator ix = clientThreads.begin();
+ for (auto ix = clientThreads.begin();
ix != clientThreads.end();
ix++) {
- stdcxx::shared_ptr<ClientThread> client
- = stdcxx::dynamic_pointer_cast<ClientThread>((*ix)->runnable());
+ std::shared_ptr<ClientThread> client
+ = std::dynamic_pointer_cast<ClientThread>((*ix)->runnable());
int64_t delta = client->_endTime - client->_startTime;
diff --git a/test/cpp/src/StressTestNonBlocking.cpp b/test/cpp/src/StressTestNonBlocking.cpp
index e68988f..e94ecb2 100644
--- a/test/cpp/src/StressTestNonBlocking.cpp
+++ b/test/cpp/src/StressTestNonBlocking.cpp
@@ -18,9 +18,8 @@
*/
#include <thrift/concurrency/ThreadManager.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/concurrency/Monitor.h>
-#include <thrift/concurrency/Util.h>
#include <thrift/concurrency/Mutex.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
@@ -33,7 +32,6 @@
#include <thrift/transport/TTransportUtils.h>
#include <thrift/transport/TFileTransport.h>
#include <thrift/TLogging.h>
-#include <thrift/stdcxx.h>
#include "Service.h"
@@ -69,7 +67,7 @@
class Server : public ServiceIf {
public:
- Server() {}
+ Server() = default;
void count(const char* method) {
Guard m(lock_);
@@ -77,7 +75,7 @@
counts_[method] = ++ct;
}
- void echoVoid() {
+ void echoVoid() override {
count("echoVoid");
// Sleep to simulate work
THRIFT_SLEEP_USEC(1);
@@ -89,18 +87,18 @@
return counts_;
}
- int8_t echoByte(const int8_t arg) { return arg; }
- int32_t echoI32(const int32_t arg) { return arg; }
- int64_t echoI64(const int64_t arg) { return arg; }
- void echoString(string& out, const string& arg) {
+ int8_t echoByte(const int8_t arg) override { return arg; }
+ int32_t echoI32(const int32_t arg) override { return arg; }
+ int64_t echoI64(const int64_t arg) override { return arg; }
+ void echoString(string& out, const string& arg) override {
if (arg != "hello") {
T_ERROR_ABORT("WRONG STRING (%s)!!!!", arg.c_str());
}
out = arg;
}
- void echoList(vector<int8_t>& out, const vector<int8_t>& arg) { out = arg; }
- void echoSet(set<int8_t>& out, const set<int8_t>& arg) { out = arg; }
- void echoMap(map<int8_t, int8_t>& out, const map<int8_t, int8_t>& arg) { out = arg; }
+ void echoList(vector<int8_t>& out, const vector<int8_t>& arg) override { out = arg; }
+ void echoSet(set<int8_t>& out, const set<int8_t>& arg) override { out = arg; }
+ void echoMap(map<int8_t, int8_t>& out, const map<int8_t, int8_t>& arg) override { out = arg; }
private:
count_map counts_;
@@ -109,8 +107,8 @@
class ClientThread : public Runnable {
public:
- ClientThread(stdcxx::shared_ptr<TTransport> transport,
- stdcxx::shared_ptr<ServiceClient> client,
+ ClientThread(std::shared_ptr<TTransport> transport,
+ std::shared_ptr<ServiceClient> client,
Monitor& monitor,
size_t& workerCount,
size_t loopCount,
@@ -122,7 +120,7 @@
_loopCount(loopCount),
_loopType(loopType) {}
- void run() {
+ void run() override {
// Wait for all worker threads to start
@@ -133,7 +131,7 @@
}
}
- _startTime = Util::currentTime();
+ _startTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
_transport->open();
@@ -158,7 +156,7 @@
break;
}
- _endTime = Util::currentTime();
+ _endTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
_transport->close();
@@ -221,8 +219,8 @@
}
}
- stdcxx::shared_ptr<TTransport> _transport;
- stdcxx::shared_ptr<ServiceClient> _client;
+ std::shared_ptr<TTransport> _transport;
+ std::shared_ptr<ServiceClient> _client;
Monitor& _monitor;
size_t& _workerCount;
size_t _loopCount;
@@ -344,24 +342,24 @@
cerr << usage.str();
}
- stdcxx::shared_ptr<PlatformThreadFactory> threadFactory
- = stdcxx::shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory());
+ std::shared_ptr<ThreadFactory> threadFactory
+ = std::shared_ptr<ThreadFactory>(new ThreadFactory());
// Dispatcher
- stdcxx::shared_ptr<Server> serviceHandler(new Server());
+ std::shared_ptr<Server> serviceHandler(new Server());
if (replayRequests) {
- stdcxx::shared_ptr<Server> serviceHandler(new Server());
- stdcxx::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
+ std::shared_ptr<Server> serviceHandler(new Server());
+ std::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
// Transports
- stdcxx::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
+ std::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
fileTransport->setChunkSize(2 * 1024 * 1024);
fileTransport->setMaxEventSize(1024 * 16);
fileTransport->seekToEnd();
// Protocol Factory
- stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
+ std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TFileProcessor fileProcessor(serviceProcessor, protocolFactory, fileTransport);
@@ -371,50 +369,50 @@
if (runServer) {
- stdcxx::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
+ std::shared_ptr<ServiceProcessor> serviceProcessor(new ServiceProcessor(serviceHandler));
// Protocol Factory
- stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
+ std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
// Transport Factory
- stdcxx::shared_ptr<TTransportFactory> transportFactory;
+ std::shared_ptr<TTransportFactory> transportFactory;
if (logRequests) {
// initialize the log file
- stdcxx::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
+ std::shared_ptr<TFileTransport> fileTransport(new TFileTransport(requestLogPath));
fileTransport->setChunkSize(2 * 1024 * 1024);
fileTransport->setMaxEventSize(1024 * 16);
transportFactory
- = stdcxx::shared_ptr<TTransportFactory>(new TPipedTransportFactory(fileTransport));
+ = std::shared_ptr<TTransportFactory>(new TPipedTransportFactory(fileTransport));
}
- stdcxx::shared_ptr<Thread> serverThread;
- stdcxx::shared_ptr<Thread> serverThread2;
- stdcxx::shared_ptr<transport::TNonblockingServerSocket> nbSocket1;
- stdcxx::shared_ptr<transport::TNonblockingServerSocket> nbSocket2;
+ std::shared_ptr<Thread> serverThread;
+ std::shared_ptr<Thread> serverThread2;
+ std::shared_ptr<transport::TNonblockingServerSocket> nbSocket1;
+ std::shared_ptr<transport::TNonblockingServerSocket> nbSocket2;
if (serverType == "simple") {
nbSocket1.reset(new transport::TNonblockingServerSocket(port));
- serverThread = threadFactory->newThread(stdcxx::shared_ptr<TServer>(
+ serverThread = threadFactory->newThread(std::shared_ptr<TServer>(
new TNonblockingServer(serviceProcessor, protocolFactory, nbSocket1)));
nbSocket2.reset(new transport::TNonblockingServerSocket(port + 1));
- serverThread2 = threadFactory->newThread(stdcxx::shared_ptr<TServer>(
+ serverThread2 = threadFactory->newThread(std::shared_ptr<TServer>(
new TNonblockingServer(serviceProcessor, protocolFactory, nbSocket2)));
} else if (serverType == "thread-pool") {
- stdcxx::shared_ptr<ThreadManager> threadManager
+ std::shared_ptr<ThreadManager> threadManager
= ThreadManager::newSimpleThreadManager(workerCount);
threadManager->threadFactory(threadFactory);
threadManager->start();
nbSocket1.reset(new transport::TNonblockingServerSocket(port));
- serverThread = threadFactory->newThread(stdcxx::shared_ptr<TServer>(
+ serverThread = threadFactory->newThread(std::shared_ptr<TServer>(
new TNonblockingServer(serviceProcessor, protocolFactory, nbSocket1, threadManager)));
nbSocket2.reset(new transport::TNonblockingServerSocket(port + 1));
- serverThread2 = threadFactory->newThread(stdcxx::shared_ptr<TServer>(
+ serverThread2 = threadFactory->newThread(std::shared_ptr<TServer>(
new TNonblockingServer(serviceProcessor, protocolFactory, nbSocket2, threadManager)));
}
@@ -437,7 +435,7 @@
size_t threadCount = 0;
- set<stdcxx::shared_ptr<Thread> > clientThreads;
+ set<std::shared_ptr<Thread> > clientThreads;
if (callName == "echoVoid") {
loopType = T_VOID;
@@ -455,16 +453,16 @@
for (uint32_t ix = 0; ix < clientCount; ix++) {
- stdcxx::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port + (ix % 2)));
- stdcxx::shared_ptr<TFramedTransport> framedSocket(new TFramedTransport(socket));
- stdcxx::shared_ptr<TProtocol> protocol(new TBinaryProtocol(framedSocket));
- stdcxx::shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
+ std::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", port + (ix % 2)));
+ std::shared_ptr<TFramedTransport> framedSocket(new TFramedTransport(socket));
+ std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(framedSocket));
+ std::shared_ptr<ServiceClient> serviceClient(new ServiceClient(protocol));
- clientThreads.insert(threadFactory->newThread(stdcxx::shared_ptr<ClientThread>(
+ clientThreads.insert(threadFactory->newThread(std::shared_ptr<ClientThread>(
new ClientThread(socket, serviceClient, monitor, threadCount, loopCount, loopType))));
}
- for (std::set<stdcxx::shared_ptr<Thread> >::const_iterator thread = clientThreads.begin();
+ for (auto thread = clientThreads.begin();
thread != clientThreads.end();
thread++) {
(*thread)->start();
@@ -479,7 +477,7 @@
cerr << "Launch " << clientCount << " client threads" << endl;
- time00 = Util::currentTime();
+ time00 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
monitor.notifyAll();
@@ -487,7 +485,7 @@
monitor.wait();
}
- time01 = Util::currentTime();
+ time01 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
int64_t firstTime = 9223372036854775807LL;
@@ -497,12 +495,12 @@
int64_t minTime = 9223372036854775807LL;
int64_t maxTime = 0;
- for (set<stdcxx::shared_ptr<Thread> >::iterator ix = clientThreads.begin();
+ for (auto ix = clientThreads.begin();
ix != clientThreads.end();
ix++) {
- stdcxx::shared_ptr<ClientThread> client
- = stdcxx::dynamic_pointer_cast<ClientThread>((*ix)->runnable());
+ std::shared_ptr<ClientThread> client
+ = std::dynamic_pointer_cast<ClientThread>((*ix)->runnable());
int64_t delta = client->_endTime - client->_startTime;
diff --git a/test/cpp/src/TestClient.cpp b/test/cpp/src/TestClient.cpp
index ca21326..c4146cc 100644
--- a/test/cpp/src/TestClient.cpp
+++ b/test/cpp/src/TestClient.cpp
@@ -46,7 +46,6 @@
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <boost/random/random_device.hpp>
-#include <thrift/stdcxx.h>
#if _WIN32
#include <thrift/windows/TWinsockSingleton.h>
#endif
@@ -61,12 +60,59 @@
using namespace apache::thrift::transport;
using namespace thrift::test;
+//
+// A pedantic protocol that checks to make sure the response sequence ID
+// is the same as the sent sequence ID. lib/cpp always sends zero for
+// synchronous clients, so this bumps the number to make sure it gets
+// returned properly from the remote server. Any server that does not
+// respond with the same sequence number is violating the sequence ID
+// agreement between client and server.
+//
+
+template<typename Proto>
+class TPedanticProtocol : public Proto
+{
+ public:
+ TPedanticProtocol(std::shared_ptr<TTransport>& transport)
+ : Proto(transport), m_last_seqid((std::numeric_limits<int32_t>::max)() - 10) { }
+
+ virtual uint32_t writeMessageBegin_virt(const std::string& name,
+ const TMessageType messageType,
+ const int32_t in_seqid) override
+ {
+ int32_t seqid = in_seqid;
+ if (!seqid) { // this is typical for normal cpp generated code
+ seqid = ++m_last_seqid;
+ }
+
+ return Proto::writeMessageBegin_virt(name, messageType, seqid);
+ }
+
+ virtual uint32_t readMessageBegin_virt(std::string& name,
+ TMessageType& messageType,
+ int32_t& seqid) override
+ {
+ uint32_t result = Proto::readMessageBegin_virt(name, messageType, seqid);
+ if (seqid != m_last_seqid) {
+ std::stringstream ss;
+ ss << "ERROR: send request with seqid " << m_last_seqid << " and got reply with seqid " << seqid;
+ throw std::logic_error(ss.str());
+ } /* else {
+ std::cout << "verified seqid " << m_last_seqid << " round trip OK" << std::endl;
+ } */
+ return result;
+ }
+
+ private:
+ int32_t m_last_seqid;
+};
+
// Current time, microseconds since the epoch
uint64_t now() {
int64_t ret;
struct timeval tv;
- THRIFT_GETTIMEOFDAY(&tv, NULL);
+ THRIFT_GETTIMEOFDAY(&tv, nullptr);
ret = tv.tv_sec;
ret = ret * 1000 * 1000 + tv.tv_usec;
return ret;
@@ -98,10 +144,10 @@
for (int testNr = 0; testNr < 10; ++testNr) {
std::ostringstream os;
os << "test" << testNr;
- client->testString(stdcxx::bind(testString_clientReturn,
+ client->testString(std::bind(testString_clientReturn,
base,
testNr,
- stdcxx::placeholders::_1),
+ std::placeholders::_1),
os.str());
}
} catch (TException& exn) {
@@ -254,18 +300,18 @@
}
// THRIFT-4164: The factory MUST outlive any sockets it creates for correct behavior!
- stdcxx::shared_ptr<TSSLSocketFactory> factory;
- stdcxx::shared_ptr<TSocket> socket;
- stdcxx::shared_ptr<TTransport> transport;
- stdcxx::shared_ptr<TProtocol> protocol;
- stdcxx::shared_ptr<TProtocol> protocol2; // SecondService for multiplexed
+ std::shared_ptr<TSSLSocketFactory> factory;
+ std::shared_ptr<TSocket> socket;
+ std::shared_ptr<TTransport> transport;
+ std::shared_ptr<TProtocol> protocol;
+ std::shared_ptr<TProtocol> protocol2; // SecondService for multiplexed
if (ssl) {
cout << "Client Certificate File: " << certPath << endl;
cout << "Client Key File: " << keyPath << endl;
cout << "CA File: " << caPath << endl;
- factory = stdcxx::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
+ factory = std::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
factory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
factory->loadTrustedCertificates(caPath.c_str());
factory->loadCertificate(certPath.c_str());
@@ -277,42 +323,46 @@
if (abstract_namespace) {
std::string abstract_socket("\0", 1);
abstract_socket += domain_socket;
- socket = stdcxx::shared_ptr<TSocket>(new TSocket(abstract_socket));
+ socket = std::shared_ptr<TSocket>(new TSocket(abstract_socket));
} else {
- socket = stdcxx::shared_ptr<TSocket>(new TSocket(domain_socket));
+ socket = std::shared_ptr<TSocket>(new TSocket(domain_socket));
}
port = 0;
} else {
- socket = stdcxx::shared_ptr<TSocket>(new TSocket(host, port));
+ socket = std::shared_ptr<TSocket>(new TSocket(host, port));
}
}
if (transport_type.compare("http") == 0) {
- transport = stdcxx::make_shared<THttpClient>(socket, host, "/service");
+ transport = std::make_shared<THttpClient>(socket, host, "/service");
} else if (transport_type.compare("framed") == 0) {
- transport = stdcxx::make_shared<TFramedTransport>(socket);
+ transport = std::make_shared<TFramedTransport>(socket);
} else {
- transport = stdcxx::make_shared<TBufferedTransport>(socket);
+ transport = std::make_shared<TBufferedTransport>(socket);
}
if (zlib) {
- transport = stdcxx::make_shared<TZlibTransport>(transport);
+ transport = std::make_shared<TZlibTransport>(transport);
}
if (protocol_type == "json" || protocol_type == "multij") {
- protocol = stdcxx::make_shared<TJSONProtocol>(transport);
+ typedef TPedanticProtocol<TJSONProtocol> TPedanticJSONProtocol;
+ protocol = std::make_shared<TPedanticJSONProtocol>(transport);
} else if (protocol_type == "compact" || protocol_type == "multic") {
- protocol = stdcxx::make_shared<TCompactProtocol>(transport);
+ typedef TPedanticProtocol<TCompactProtocol> TPedanticCompactProtocol;
+ protocol = std::make_shared<TPedanticCompactProtocol>(transport);
} else if (protocol_type == "header" || protocol_type == "multih") {
- protocol = stdcxx::make_shared<THeaderProtocol>(transport);
+ typedef TPedanticProtocol<THeaderProtocol> TPedanticHeaderProtocol;
+ protocol = std::make_shared<TPedanticHeaderProtocol>(transport);
} else {
- protocol = stdcxx::make_shared<TBinaryProtocol>(transport);
+ typedef TPedanticProtocol<TBinaryProtocol> TPedanticBinaryProtocol;
+ protocol = std::make_shared<TPedanticBinaryProtocol>(transport);
}
if (boost::starts_with(protocol_type, "multi")) {
- protocol2 = stdcxx::make_shared<TMultiplexedProtocol>(protocol, "SecondService");
- // we don't need access to the original protocol any more, so...
- protocol = stdcxx::make_shared<TMultiplexedProtocol>(protocol, "ThriftTest");
+ protocol2 = std::make_shared<TMultiplexedProtocol>(protocol, "SecondService");
+ // we don't need access to the original protocol any more, so...
+ protocol = std::make_shared<TMultiplexedProtocol>(protocol, "ThriftTest");
}
// Connection info
@@ -334,14 +384,14 @@
cout << "Libevent Features: 0x" << hex << event_base_get_features(base) << endl;
#endif
- stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
+ std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
- stdcxx::shared_ptr<TAsyncChannel> channel(
+ std::shared_ptr<TAsyncChannel> channel(
new TEvhttpClientChannel(host.c_str(), "/", host.c_str(), port, base));
ThriftTestCobClient* client = new ThriftTestCobClient(channel, protocolFactory.get());
- client->testVoid(stdcxx::bind(testVoid_clientReturn,
+ client->testVoid(std::bind(testVoid_clientReturn,
base,
- stdcxx::placeholders::_1));
+ std::placeholders::_1));
event_base_loop(base, 0);
return 0;
@@ -943,11 +993,11 @@
if (it1 == whoa.end()) {
failed = true;
} else {
- map<Numberz::type, Insanity>::const_iterator it12 = it1->second.find(Numberz::TWO);
+ auto it12 = it1->second.find(Numberz::TWO);
if (it12 == it1->second.end() || it12->second != insane) {
failed = true;
}
- map<Numberz::type, Insanity>::const_iterator it13 = it1->second.find(Numberz::THREE);
+ auto it13 = it1->second.find(Numberz::THREE);
if (it13 == it1->second.end() || it13->second != insane) {
failed = true;
}
@@ -956,7 +1006,7 @@
if (it2 == whoa.end()) {
failed = true;
} else {
- map<Numberz::type, Insanity>::const_iterator it26 = it2->second.find(Numberz::SIX);
+ auto it26 = it2->second.find(Numberz::SIX);
if (it26 == it2->second.end() || it26->second != Insanity()) {
failed = true;
}
diff --git a/test/cpp/src/TestServer.cpp b/test/cpp/src/TestServer.cpp
index 323f873..8d5b4d9 100644
--- a/test/cpp/src/TestServer.cpp
+++ b/test/cpp/src/TestServer.cpp
@@ -20,7 +20,7 @@
#include <thrift/async/TAsyncBufferProcessor.h>
#include <thrift/async/TAsyncProtocolProcessor.h>
#include <thrift/async/TEvhttpServer.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/concurrency/ThreadManager.h>
#include <thrift/processor/TMultiplexedProcessor.h>
#include <thrift/protocol/TBinaryProtocol.h>
@@ -61,7 +61,6 @@
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
-#include <thrift/stdcxx.h>
#if _WIN32
#include <thrift/windows/TWinsockSingleton.h>
@@ -91,48 +90,48 @@
class TestHandler : public ThriftTestIf {
public:
- TestHandler() {}
+ TestHandler() = default;
- void testVoid() { printf("testVoid()\n"); }
+ void testVoid() override { printf("testVoid()\n"); }
- void testString(string& out, const string& thing) {
+ void testString(string& out, const string& thing) override {
printf("testString(\"%s\")\n", thing.c_str());
out = thing;
}
- bool testBool(const bool thing) {
+ bool testBool(const bool thing) override {
printf("testBool(%s)\n", thing ? "true" : "false");
return thing;
}
- int8_t testByte(const int8_t thing) {
+ int8_t testByte(const int8_t thing) override {
printf("testByte(%d)\n", (int)thing);
return thing;
}
- int32_t testI32(const int32_t thing) {
+ int32_t testI32(const int32_t thing) override {
printf("testI32(%d)\n", thing);
return thing;
}
- int64_t testI64(const int64_t thing) {
+ int64_t testI64(const int64_t thing) override {
printf("testI64(%" PRId64 ")\n", thing);
return thing;
}
- double testDouble(const double thing) {
+ double testDouble(const double thing) override {
printf("testDouble(%f)\n", thing);
return thing;
}
- void testBinary(std::string& _return, const std::string& thing) {
+ void testBinary(std::string& _return, const std::string& thing) override {
std::ostringstream hexstr;
hexstr << std::hex << thing;
printf("testBinary(%lu: %s)\n", safe_numeric_cast<unsigned long>(thing.size()), hexstr.str().c_str());
_return = thing;
}
- void testStruct(Xtruct& out, const Xtruct& thing) {
+ void testStruct(Xtruct& out, const Xtruct& thing) override {
printf("testStruct({\"%s\", %d, %d, %" PRId64 "})\n",
thing.string_thing.c_str(),
(int)thing.byte_thing,
@@ -141,7 +140,7 @@
out = thing;
}
- void testNest(Xtruct2& out, const Xtruct2& nest) {
+ void testNest(Xtruct2& out, const Xtruct2& nest) override {
const Xtruct& thing = nest.struct_thing;
printf("testNest({%d, {\"%s\", %d, %d, %" PRId64 "}, %d})\n",
(int)nest.byte_thing,
@@ -153,7 +152,7 @@
out = nest;
}
- void testMap(map<int32_t, int32_t>& out, const map<int32_t, int32_t>& thing) {
+ void testMap(map<int32_t, int32_t>& out, const map<int32_t, int32_t>& thing) override {
printf("testMap({");
map<int32_t, int32_t>::const_iterator m_iter;
bool first = true;
@@ -170,7 +169,7 @@
}
void testStringMap(map<std::string, std::string>& out,
- const map<std::string, std::string>& thing) {
+ const map<std::string, std::string>& thing) override {
printf("testMap({");
map<std::string, std::string>::const_iterator m_iter;
bool first = true;
@@ -186,7 +185,7 @@
out = thing;
}
- void testSet(set<int32_t>& out, const set<int32_t>& thing) {
+ void testSet(set<int32_t>& out, const set<int32_t>& thing) override {
printf("testSet({");
set<int32_t>::const_iterator s_iter;
bool first = true;
@@ -202,7 +201,7 @@
out = thing;
}
- void testList(vector<int32_t>& out, const vector<int32_t>& thing) {
+ void testList(vector<int32_t>& out, const vector<int32_t>& thing) override {
printf("testList({");
vector<int32_t>::const_iterator l_iter;
bool first = true;
@@ -218,17 +217,17 @@
out = thing;
}
- Numberz::type testEnum(const Numberz::type thing) {
+ Numberz::type testEnum(const Numberz::type thing) override {
printf("testEnum(%d)\n", thing);
return thing;
}
- UserId testTypedef(const UserId thing) {
+ UserId testTypedef(const UserId thing) override {
printf("testTypedef(%" PRId64 ")\n", thing);
return thing;
}
- void testMapMap(map<int32_t, map<int32_t, int32_t> >& mapmap, const int32_t hello) {
+ void testMapMap(map<int32_t, map<int32_t, int32_t> >& mapmap, const int32_t hello) override {
printf("testMapMap(%d)\n", hello);
map<int32_t, int32_t> pos;
@@ -242,7 +241,7 @@
mapmap.insert(make_pair(-4, neg));
}
- void testInsanity(map<UserId, map<Numberz::type, Insanity> >& insane, const Insanity& argument) {
+ void testInsanity(map<UserId, map<Numberz::type, Insanity> >& insane, const Insanity& argument) override {
printf("testInsanity()\n");
Insanity looney;
@@ -298,7 +297,7 @@
const int64_t arg2,
const std::map<int16_t, std::string>& arg3,
const Numberz::type arg4,
- const UserId arg5) {
+ const UserId arg5) override {
(void)arg3;
(void)arg4;
(void)arg5;
@@ -311,7 +310,7 @@
hello.i64_thing = (int64_t)arg2;
}
- void testException(const std::string& arg) {
+ void testException(const std::string& arg) override {
printf("testException(%s)\n", arg.c_str());
if (arg.compare("Xception") == 0) {
Xception e;
@@ -330,7 +329,7 @@
void testMultiException(Xtruct& result,
const std::string& arg0,
- const std::string& arg1) {
+ const std::string& arg1) override {
printf("testMultiException(%s, %s)\n", arg0.c_str(), arg1.c_str());
@@ -350,7 +349,7 @@
}
}
- void testOneway(const int32_t aNum) {
+ void testOneway(const int32_t aNum) override {
printf("testOneway(%d): call received\n", aNum);
}
};
@@ -358,33 +357,33 @@
class SecondHandler : public SecondServiceIf
{
public:
- void secondtestString(std::string& result, const std::string& thing)
+ void secondtestString(std::string& result, const std::string& thing) override
{ result = "testString(\"" + thing + "\")"; }
};
class TestProcessorEventHandler : public TProcessorEventHandler {
- virtual void* getContext(const char* fn_name, void* serverContext) {
+ void* getContext(const char* fn_name, void* serverContext) override {
(void)serverContext;
return new std::string(fn_name);
}
- virtual void freeContext(void* ctx, const char* fn_name) {
+ void freeContext(void* ctx, const char* fn_name) override {
(void)fn_name;
delete static_cast<std::string*>(ctx);
}
- virtual void preRead(void* ctx, const char* fn_name) { communicate("preRead", ctx, fn_name); }
- virtual void postRead(void* ctx, const char* fn_name, uint32_t bytes) {
+ void preRead(void* ctx, const char* fn_name) override { communicate("preRead", ctx, fn_name); }
+ void postRead(void* ctx, const char* fn_name, uint32_t bytes) override {
(void)bytes;
communicate("postRead", ctx, fn_name);
}
- virtual void preWrite(void* ctx, const char* fn_name) { communicate("preWrite", ctx, fn_name); }
- virtual void postWrite(void* ctx, const char* fn_name, uint32_t bytes) {
+ void preWrite(void* ctx, const char* fn_name) override { communicate("preWrite", ctx, fn_name); }
+ void postWrite(void* ctx, const char* fn_name, uint32_t bytes) override {
(void)bytes;
communicate("postWrite", ctx, fn_name);
}
- virtual void asyncComplete(void* ctx, const char* fn_name) {
+ void asyncComplete(void* ctx, const char* fn_name) override {
communicate("asyncComplete", ctx, fn_name);
}
- virtual void handlerError(void* ctx, const char* fn_name) {
+ void handlerError(void* ctx, const char* fn_name) override {
communicate("handlerError", ctx, fn_name);
}
@@ -395,137 +394,137 @@
class TestHandlerAsync : public ThriftTestCobSvIf {
public:
- TestHandlerAsync(stdcxx::shared_ptr<TestHandler>& handler) : _delegate(handler) {}
- virtual ~TestHandlerAsync() {}
+ TestHandlerAsync(std::shared_ptr<TestHandler>& handler) : _delegate(handler) {}
+ ~TestHandlerAsync() override = default;
- virtual void testVoid(stdcxx::function<void()> cob) {
+ void testVoid(std::function<void()> cob) override {
_delegate->testVoid();
cob();
}
- virtual void testString(stdcxx::function<void(std::string const& _return)> cob,
- const std::string& thing) {
+ void testString(std::function<void(std::string const& _return)> cob,
+ const std::string& thing) override {
std::string res;
_delegate->testString(res, thing);
cob(res);
}
- virtual void testBool(stdcxx::function<void(bool const& _return)> cob, const bool thing) {
+ void testBool(std::function<void(bool const& _return)> cob, const bool thing) override {
bool res = _delegate->testBool(thing);
cob(res);
}
- virtual void testByte(stdcxx::function<void(int8_t const& _return)> cob, const int8_t thing) {
+ void testByte(std::function<void(int8_t const& _return)> cob, const int8_t thing) override {
int8_t res = _delegate->testByte(thing);
cob(res);
}
- virtual void testI32(stdcxx::function<void(int32_t const& _return)> cob, const int32_t thing) {
+ void testI32(std::function<void(int32_t const& _return)> cob, const int32_t thing) override {
int32_t res = _delegate->testI32(thing);
cob(res);
}
- virtual void testI64(stdcxx::function<void(int64_t const& _return)> cob, const int64_t thing) {
+ void testI64(std::function<void(int64_t const& _return)> cob, const int64_t thing) override {
int64_t res = _delegate->testI64(thing);
cob(res);
}
- virtual void testDouble(stdcxx::function<void(double const& _return)> cob, const double thing) {
+ void testDouble(std::function<void(double const& _return)> cob, const double thing) override {
double res = _delegate->testDouble(thing);
cob(res);
}
- virtual void testBinary(stdcxx::function<void(std::string const& _return)> cob,
- const std::string& thing) {
+ void testBinary(std::function<void(std::string const& _return)> cob,
+ const std::string& thing) override {
std::string res;
_delegate->testBinary(res, thing);
cob(res);
}
- virtual void testStruct(stdcxx::function<void(Xtruct const& _return)> cob, const Xtruct& thing) {
+ void testStruct(std::function<void(Xtruct const& _return)> cob, const Xtruct& thing) override {
Xtruct res;
_delegate->testStruct(res, thing);
cob(res);
}
- virtual void testNest(stdcxx::function<void(Xtruct2 const& _return)> cob, const Xtruct2& thing) {
+ void testNest(std::function<void(Xtruct2 const& _return)> cob, const Xtruct2& thing) override {
Xtruct2 res;
_delegate->testNest(res, thing);
cob(res);
}
- virtual void testMap(stdcxx::function<void(std::map<int32_t, int32_t> const& _return)> cob,
- const std::map<int32_t, int32_t>& thing) {
+ void testMap(std::function<void(std::map<int32_t, int32_t> const& _return)> cob,
+ const std::map<int32_t, int32_t>& thing) override {
std::map<int32_t, int32_t> res;
_delegate->testMap(res, thing);
cob(res);
}
- virtual void testStringMap(
- stdcxx::function<void(std::map<std::string, std::string> const& _return)> cob,
- const std::map<std::string, std::string>& thing) {
+ void testStringMap(
+ std::function<void(std::map<std::string, std::string> const& _return)> cob,
+ const std::map<std::string, std::string>& thing) override {
std::map<std::string, std::string> res;
_delegate->testStringMap(res, thing);
cob(res);
}
- virtual void testSet(stdcxx::function<void(std::set<int32_t> const& _return)> cob,
- const std::set<int32_t>& thing) {
+ void testSet(std::function<void(std::set<int32_t> const& _return)> cob,
+ const std::set<int32_t>& thing) override {
std::set<int32_t> res;
_delegate->testSet(res, thing);
cob(res);
}
- virtual void testList(stdcxx::function<void(std::vector<int32_t> const& _return)> cob,
- const std::vector<int32_t>& thing) {
+ void testList(std::function<void(std::vector<int32_t> const& _return)> cob,
+ const std::vector<int32_t>& thing) override {
std::vector<int32_t> res;
_delegate->testList(res, thing);
cob(res);
}
- virtual void testEnum(stdcxx::function<void(Numberz::type const& _return)> cob,
- const Numberz::type thing) {
+ void testEnum(std::function<void(Numberz::type const& _return)> cob,
+ const Numberz::type thing) override {
Numberz::type res = _delegate->testEnum(thing);
cob(res);
}
- virtual void testTypedef(stdcxx::function<void(UserId const& _return)> cob, const UserId thing) {
+ void testTypedef(std::function<void(UserId const& _return)> cob, const UserId thing) override {
UserId res = _delegate->testTypedef(thing);
cob(res);
}
- virtual void testMapMap(
- stdcxx::function<void(std::map<int32_t, std::map<int32_t, int32_t> > const& _return)> cob,
- const int32_t hello) {
+ void testMapMap(
+ std::function<void(std::map<int32_t, std::map<int32_t, int32_t> > const& _return)> cob,
+ const int32_t hello) override {
std::map<int32_t, std::map<int32_t, int32_t> > res;
_delegate->testMapMap(res, hello);
cob(res);
}
- virtual void testInsanity(
- stdcxx::function<void(std::map<UserId, std::map<Numberz::type, Insanity> > const& _return)> cob,
- const Insanity& argument) {
+ void testInsanity(
+ std::function<void(std::map<UserId, std::map<Numberz::type, Insanity> > const& _return)> cob,
+ const Insanity& argument) override {
std::map<UserId, std::map<Numberz::type, Insanity> > res;
_delegate->testInsanity(res, argument);
cob(res);
}
- virtual void testMulti(stdcxx::function<void(Xtruct const& _return)> cob,
+ void testMulti(std::function<void(Xtruct const& _return)> cob,
const int8_t arg0,
const int32_t arg1,
const int64_t arg2,
const std::map<int16_t, std::string>& arg3,
const Numberz::type arg4,
- const UserId arg5) {
+ const UserId arg5) override {
Xtruct res;
_delegate->testMulti(res, arg0, arg1, arg2, arg3, arg4, arg5);
cob(res);
}
- virtual void testException(
- stdcxx::function<void()> cob,
- stdcxx::function<void(::apache::thrift::TDelayedException* _throw)> exn_cob,
- const std::string& arg) {
+ void testException(
+ std::function<void()> cob,
+ std::function<void(::apache::thrift::TDelayedException* _throw)> exn_cob,
+ const std::string& arg) override {
try {
_delegate->testException(arg);
} catch (const apache::thrift::TException& e) {
@@ -535,11 +534,11 @@
cob();
}
- virtual void testMultiException(
- stdcxx::function<void(Xtruct const& _return)> cob,
- stdcxx::function<void(::apache::thrift::TDelayedException* _throw)> exn_cob,
+ void testMultiException(
+ std::function<void(Xtruct const& _return)> cob,
+ std::function<void(::apache::thrift::TDelayedException* _throw)> exn_cob,
const std::string& arg0,
- const std::string& arg1) {
+ const std::string& arg1) override {
Xtruct res;
try {
_delegate->testMultiException(res, arg0, arg1);
@@ -550,13 +549,13 @@
cob(res);
}
- virtual void testOneway(stdcxx::function<void()> cob, const int32_t secondsToSleep) {
+ void testOneway(std::function<void()> cob, const int32_t secondsToSleep) override {
_delegate->testOneway(secondsToSleep);
cob();
}
protected:
- stdcxx::shared_ptr<TestHandler> _delegate;
+ std::shared_ptr<TestHandler> _delegate;
};
namespace po = boost::program_options;
@@ -668,76 +667,76 @@
}
// Dispatcher
- stdcxx::shared_ptr<TProtocolFactory> protocolFactory;
+ std::shared_ptr<TProtocolFactory> protocolFactory;
if (protocol_type == "json" || protocol_type == "multij") {
- stdcxx::shared_ptr<TProtocolFactory> jsonProtocolFactory(new TJSONProtocolFactory());
+ std::shared_ptr<TProtocolFactory> jsonProtocolFactory(new TJSONProtocolFactory());
protocolFactory = jsonProtocolFactory;
} else if (protocol_type == "compact" || protocol_type == "multic") {
- TCompactProtocolFactoryT<TBufferBase> *compactProtocolFactory = new TCompactProtocolFactoryT<TBufferBase>();
+ auto *compactProtocolFactory = new TCompactProtocolFactoryT<TBufferBase>();
compactProtocolFactory->setContainerSizeLimit(container_limit);
compactProtocolFactory->setStringSizeLimit(string_limit);
protocolFactory.reset(compactProtocolFactory);
} else if (protocol_type == "header" || protocol_type == "multih") {
- stdcxx::shared_ptr<TProtocolFactory> headerProtocolFactory(new THeaderProtocolFactory());
+ std::shared_ptr<TProtocolFactory> headerProtocolFactory(new THeaderProtocolFactory());
protocolFactory = headerProtocolFactory;
} else {
- TBinaryProtocolFactoryT<TBufferBase>* binaryProtocolFactory = new TBinaryProtocolFactoryT<TBufferBase>();
+ auto* binaryProtocolFactory = new TBinaryProtocolFactoryT<TBufferBase>();
binaryProtocolFactory->setContainerSizeLimit(container_limit);
binaryProtocolFactory->setStringSizeLimit(string_limit);
protocolFactory.reset(binaryProtocolFactory);
}
// Processors
- stdcxx::shared_ptr<TestHandler> testHandler(new TestHandler());
- stdcxx::shared_ptr<TProcessor> testProcessor(new ThriftTestProcessor(testHandler));
+ std::shared_ptr<TestHandler> testHandler(new TestHandler());
+ std::shared_ptr<TProcessor> testProcessor(new ThriftTestProcessor(testHandler));
if (vm.count("processor-events")) {
testProcessor->setEventHandler(
- stdcxx::shared_ptr<TProcessorEventHandler>(new TestProcessorEventHandler()));
+ std::shared_ptr<TProcessorEventHandler>(new TestProcessorEventHandler()));
}
// Transport
- stdcxx::shared_ptr<TSSLSocketFactory> sslSocketFactory;
- stdcxx::shared_ptr<TServerSocket> serverSocket;
+ std::shared_ptr<TSSLSocketFactory> sslSocketFactory;
+ std::shared_ptr<TServerSocket> serverSocket;
if (ssl) {
- sslSocketFactory = stdcxx::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
+ sslSocketFactory = std::shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
sslSocketFactory->loadCertificate(certPath.c_str());
sslSocketFactory->loadPrivateKey(keyPath.c_str());
sslSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
if (server_type != "nonblocking") {
- serverSocket = stdcxx::shared_ptr<TServerSocket>(new TSSLServerSocket(port, sslSocketFactory));
+ serverSocket = std::shared_ptr<TServerSocket>(new TSSLServerSocket(port, sslSocketFactory));
}
} else {
if (domain_socket != "") {
if (abstract_namespace) {
std::string abstract_socket("\0", 1);
abstract_socket += domain_socket;
- serverSocket = stdcxx::shared_ptr<TServerSocket>(new TServerSocket(abstract_socket));
+ serverSocket = std::shared_ptr<TServerSocket>(new TServerSocket(abstract_socket));
} else {
unlink(domain_socket.c_str());
- serverSocket = stdcxx::shared_ptr<TServerSocket>(new TServerSocket(domain_socket));
+ serverSocket = std::shared_ptr<TServerSocket>(new TServerSocket(domain_socket));
}
port = 0;
} else {
- serverSocket = stdcxx::shared_ptr<TServerSocket>(new TServerSocket(port));
+ serverSocket = std::shared_ptr<TServerSocket>(new TServerSocket(port));
}
}
// Factory
- stdcxx::shared_ptr<TTransportFactory> transportFactory;
+ std::shared_ptr<TTransportFactory> transportFactory;
if (transport_type == "http" && server_type != "nonblocking") {
- transportFactory = stdcxx::make_shared<THttpServerTransportFactory>();
+ transportFactory = std::make_shared<THttpServerTransportFactory>();
} else if (transport_type == "framed") {
- transportFactory = stdcxx::make_shared<TFramedTransportFactory>();
+ transportFactory = std::make_shared<TFramedTransportFactory>();
} else {
- transportFactory = stdcxx::make_shared<TBufferedTransportFactory>();
+ transportFactory = std::make_shared<TBufferedTransportFactory>();
}
if (zlib) {
// hmm.. doesn't seem to be a way to make it wrap the others...
- transportFactory = stdcxx::make_shared<TZlibTransportFactory>();
+ transportFactory = std::make_shared<TZlibTransportFactory>();
}
// Server Info
@@ -754,27 +753,27 @@
// Multiplexed Processor if needed
if (boost::starts_with(protocol_type, "multi")) {
- stdcxx::shared_ptr<SecondHandler> secondHandler(new SecondHandler());
- stdcxx::shared_ptr<SecondServiceProcessor> secondProcessor(new SecondServiceProcessor(secondHandler));
+ std::shared_ptr<SecondHandler> secondHandler(new SecondHandler());
+ std::shared_ptr<SecondServiceProcessor> secondProcessor(new SecondServiceProcessor(secondHandler));
- stdcxx::shared_ptr<TMultiplexedProcessor> multiplexedProcessor(new TMultiplexedProcessor());
+ std::shared_ptr<TMultiplexedProcessor> multiplexedProcessor(new TMultiplexedProcessor());
multiplexedProcessor->registerDefault(testProcessor); // non-multi clients go to the default processor (multi:binary, multic:compact, ...)
multiplexedProcessor->registerProcessor("ThriftTest", testProcessor);
multiplexedProcessor->registerProcessor("SecondService", secondProcessor);
- testProcessor = stdcxx::dynamic_pointer_cast<TProcessor>(multiplexedProcessor);
+ testProcessor = std::dynamic_pointer_cast<TProcessor>(multiplexedProcessor);
}
// Server
- stdcxx::shared_ptr<apache::thrift::server::TServer> server;
+ std::shared_ptr<apache::thrift::server::TServer> server;
if (server_type == "simple") {
server.reset(new TSimpleServer(testProcessor, serverSocket, transportFactory, protocolFactory));
} else if (server_type == "thread-pool") {
- stdcxx::shared_ptr<PlatformThreadFactory> threadFactory
- = stdcxx::shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory());
+ std::shared_ptr<ThreadFactory> threadFactory
+ = std::shared_ptr<ThreadFactory>(new ThreadFactory());
- stdcxx::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workers);
+ std::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workers);
threadManager->threadFactory(threadFactory);
threadManager->start();
@@ -788,10 +787,10 @@
new TThreadedServer(testProcessor, serverSocket, transportFactory, protocolFactory));
} else if (server_type == "nonblocking") {
if (transport_type == "http") {
- stdcxx::shared_ptr<TestHandlerAsync> testHandlerAsync(new TestHandlerAsync(testHandler));
- stdcxx::shared_ptr<TAsyncProcessor> testProcessorAsync(
+ std::shared_ptr<TestHandlerAsync> testHandlerAsync(new TestHandlerAsync(testHandler));
+ std::shared_ptr<TAsyncProcessor> testProcessorAsync(
new ThriftTestAsyncProcessor(testHandlerAsync));
- stdcxx::shared_ptr<TAsyncBufferProcessor> testBufferProcessor(
+ std::shared_ptr<TAsyncBufferProcessor> testBufferProcessor(
new TAsyncProtocolProcessor(testProcessorAsync, protocolFactory));
// not loading nonblockingServer into "server" because
@@ -800,7 +799,7 @@
TEvhttpServer nonblockingServer(testBufferProcessor, port);
nonblockingServer.serve();
} else if (transport_type == "framed") {
- stdcxx::shared_ptr<transport::TNonblockingServerTransport> nbSocket;
+ std::shared_ptr<transport::TNonblockingServerTransport> nbSocket;
nbSocket.reset(
ssl ? new transport::TNonblockingSSLServerSocket(port, sslSocketFactory)
: new transport::TNonblockingServerSocket(port));
@@ -811,17 +810,17 @@
}
}
- if (server.get() != NULL) {
+ if (server.get() != nullptr) {
if (protocol_type == "header") {
// Tell the server to use the same protocol for input / output
// if using header
- server->setOutputProtocolFactory(stdcxx::shared_ptr<TProtocolFactory>());
+ server->setOutputProtocolFactory(std::shared_ptr<TProtocolFactory>());
}
- apache::thrift::concurrency::PlatformThreadFactory factory;
+ apache::thrift::concurrency::ThreadFactory factory;
factory.setDetached(false);
- stdcxx::shared_ptr<apache::thrift::concurrency::Runnable> serverThreadRunner(server);
- stdcxx::shared_ptr<apache::thrift::concurrency::Thread> thread
+ std::shared_ptr<apache::thrift::concurrency::Runnable> serverThreadRunner(server);
+ std::shared_ptr<apache::thrift::concurrency::Thread> thread
= factory.newThread(serverThreadRunner);
#ifdef HAVE_SIGNAL_H
diff --git a/test/crossrunner/run.py b/test/crossrunner/run.py
index ef8fb60..bb06d25 100644
--- a/test/crossrunner/run.py
+++ b/test/crossrunner/run.py
@@ -259,7 +259,7 @@
raise
logger.warn('Error executing [%s]', test.name, exc_info=True)
return (retry_count, RESULT_ERROR)
- except:
+ except Exception:
logger.info('Interrupted execution', exc_info=True)
if not async_mode:
raise
diff --git a/test/csharp/Properties/AssemblyInfo.cs b/test/csharp/Properties/AssemblyInfo.cs
index 67a9243..76c9a80 100644
--- a/test/csharp/Properties/AssemblyInfo.cs
+++ b/test/csharp/Properties/AssemblyInfo.cs
@@ -51,5 +51,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.12.1.0")]
-[assembly: AssemblyFileVersion("0.12.1.0")]
+[assembly: AssemblyVersion("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/test/csharp/ThriftTest.csproj b/test/csharp/ThriftTest.csproj
index 2ee51e1..effec19 100644
--- a/test/csharp/ThriftTest.csproj
+++ b/test/csharp/ThriftTest.csproj
@@ -46,7 +46,7 @@
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
- <ApplicationVersion>0.12.1.%2a</ApplicationVersion>
+ <ApplicationVersion>0.13.0.0</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
diff --git a/test/dart/Makefile.am b/test/dart/Makefile.am
index 9750ec2..27fdc09 100644
--- a/test/dart/Makefile.am
+++ b/test/dart/Makefile.am
@@ -33,10 +33,20 @@
check: stubs
clean-local:
- $(RM) -r gen-dart test_client/.pub
+ $(RM) -r gen-dart/ test_client/.pub
+ find . -type d -name ".dart_tool" | xargs $(RM) -r
find . -type d -name "packages" | xargs $(RM) -r
find . -type f -name ".packages" | xargs $(RM)
find . -type f -name "pubspec.lock" | xargs $(RM)
+dist-hook:
+ $(RM) -r $(distdir)/gen-dart/ $(distdir)/test_client/.pub
+ find $(distdir) -type d -name ".dart_tool" | xargs $(RM) -r
+ find $(distdir) -type d -name "packages" | xargs $(RM) -r
+ find $(distdir) -type f -name ".packages" | xargs $(RM)
+
client: stubs
${DART} test_client/bin/main.dart
+
+EXTRA_DIST = \
+ test_client
diff --git a/test/dart/test_client/bin/main.dart b/test/dart/test_client/bin/main.dart
index 996844b..feba612 100644
--- a/test/dart/test_client/bin/main.dart
+++ b/test/dart/test_client/bin/main.dart
@@ -120,7 +120,7 @@
'compact': 'TCompactProtocol',
'json': 'TJsonProtocol'
});
- parser.addFlag('verbose', defaultsTo: false);
+ parser.addFlag('verbose', defaultsTo: true);
ArgResults results;
try {
diff --git a/test/dart/test_client/pubspec.yaml b/test/dart/test_client/pubspec.yaml
index 9445722..c86225e 100644
--- a/test/dart/test_client/pubspec.yaml
+++ b/test/dart/test_client/pubspec.yaml
@@ -16,16 +16,16 @@
# under the License.
name: thrift_test_client
-version: 0.12.1
+version: 0.13.0
description: A client integration test for the Dart Thrift library
author: Apache Thrift Developers <dev@thrift.apache.org>
homepage: http://thrift.apache.org
environment:
- sdk: ">=1.13.0 <2.0.0"
+ sdk: ">=1.24.3 <3.0.0"
dependencies:
- args: ^0.13.0
+ args: ">=0.13.0 <2.0.0"
http: ^0.11.0
thrift:
path: ../../../lib/dart
@@ -33,4 +33,4 @@
path: ../gen-dart/thrift_test
dev_dependencies:
- test: "^0.12.0"
+ test: ">=0.12.30 <2.0.0"
diff --git a/test/erl/Makefile.am b/test/erl/Makefile.am
index ff25e89..81913ee 100644
--- a/test/erl/Makefile.am
+++ b/test/erl/Makefile.am
@@ -35,7 +35,17 @@
precross: .generated
$(REBAR) compile
+maintainer-clean-local:
+ $(RM) -r ebin/
+
clean:
- rm -f .generated
- rm -rf src/gen-erl
$(REBAR) clean
+ $(RM) .generated
+ $(RM) -r .rebar/
+ $(RM) -r src/gen-erl/
+
+dist-hook:
+ $(RM) $(distdir)/.generated
+ $(RM) -r $(distdir)/.rebar/
+ $(RM) -r $(distdir)/ebin/
+ $(RM) -r $(distdir)/src/gen-erl/
diff --git a/test/erl/src/thrift_test.app.src b/test/erl/src/thrift_test.app.src
index f8e550b..ffbad58 100644
--- a/test/erl/src/thrift_test.app.src
+++ b/test/erl/src/thrift_test.app.src
@@ -22,7 +22,7 @@
{description, "Thrift cross language test"},
% The version of the applicaton
- {vsn, "0.12.1"},
+ {vsn, "0.13.0"},
% All modules used by the application.
{modules, [
diff --git a/test/features/known_failures_Linux.json b/test/features/known_failures_Linux.json
index 8376968..6547860 100644
--- a/test/features/known_failures_Linux.json
+++ b/test/features/known_failures_Linux.json
@@ -46,5 +46,7 @@
"rs-limit_string_length_compact_buffered-ip",
"rs-limit_string_length_multic-compact_buffered-ip",
"netcore-limit_string_length_compact_buffered-ip",
- "netcore-limit_container_length_compact_buffered-ip"
+ "netcore-limit_container_length_compact_buffered-ip",
+ "nodejs-theader_framed_binary_header_buffered-ip",
+ "nodejs-theader_framed_compact_header_buffered-ip"
]
diff --git a/test/go/Makefile.am b/test/go/Makefile.am
index 6da8339..3cf6a70 100644
--- a/test/go/Makefile.am
+++ b/test/go/Makefile.am
@@ -58,8 +58,7 @@
GOPATH=`pwd` $(GO) test -v common/...
genmock: gopath
- GOPATH=`pwd` $(GO) install github.com/golang/mock/mockgen
- GOPATH=`pwd` bin/mockgen -destination=src/common/mock_handler.go -package=common gen/thrifttest ThriftTest
+ sh genmock.sh
EXTRA_DIST = \
src/bin \
diff --git a/test/go/genmock.sh b/test/go/genmock.sh
new file mode 100644
index 0000000..3ba41b9
--- /dev/null
+++ b/test/go/genmock.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+set -e
+
+export GOPATH=`pwd`
+export GOBIN=`pwd`/bin
+export GO111MODULE=off
+
+mkdir -p src/github.com/golang/mock
+cd src/github.com/golang
+curl -fsSL https://github.com/golang/mock/archive/v1.2.0.tar.gz -o mock.tar.gz
+tar -xzvf mock.tar.gz -C mock --strip-components=1
+cd mock/mockgen
+go install .
+cd ../../../../../
+bin/mockgen -destination=src/common/mock_handler.go -package=common gen/thrifttest ThriftTest
diff --git a/test/hs/Makefile.am b/test/hs/Makefile.am
index 1748906..817070d 100644
--- a/test/hs/Makefile.am
+++ b/test/hs/Makefile.am
@@ -30,9 +30,18 @@
sh run-test.sh Include
clean-local:
- $(RM) -r gen-hs
+ $(RM) -r gen-hs/
$(RM) *.hi
$(RM) *.o
+ $(RM) TestClient
+ $(RM) TestServer
+
+dist-hook:
+ $(RM) -r $(distdir)/gen-hs/
+ $(RM) $(distdir)/*.hi
+ $(RM) $(distdir)/*.o
+ $(RM) $(destdir)/TestClient
+ $(RM) $(destdir)/TestServer
all-local: stubs
ghc -igen-hs TestServer.hs
diff --git a/test/known_failures_Linux.json b/test/known_failures_Linux.json
index 1ab2af5..6c61d5a 100644
--- a/test/known_failures_Linux.json
+++ b/test/known_failures_Linux.json
@@ -75,6 +75,12 @@
"cpp-nodejs_multij-json_http-domain",
"cpp-nodejs_multij-json_http-ip",
"cpp-nodejs_multij-json_http-ip-ssl",
+ "cpp-nodejs_multih-header_http-ip",
+ "cpp-nodejs_multih-header_http-ip-ssl",
+ "cpp-nodejs_multih-header_http-domain",
+ "cpp-nodejs_header_http-ip",
+ "cpp-nodejs_header_http-ip-ssl",
+ "cpp-nodejs_header_http-domain",
"cpp-py3_binary-accel_http-ip",
"cpp-py3_binary-accel_http-ip-ssl",
"cpp-py3_binary_http-ip",
@@ -139,6 +145,8 @@
"cpp-py_multic_http-ip-ssl",
"cpp-py_multih-header_http-ip",
"cpp-py_multih-header_http-ip-ssl",
+ "cpp-py_multih_http-ip",
+ "cpp-py_multih_http-ip-ssl",
"cpp-py_multij-json_http-ip",
"cpp-py_multij-json_http-ip-ssl",
"cpp-py_multij_http-ip",
@@ -321,6 +329,8 @@
"hs-csharp_binary_framed-ip",
"hs-csharp_compact_buffered-ip",
"hs-csharp_compact_framed-ip",
+ "hs-csharp_json_buffered-ip",
+ "hs-csharp_json_framed-ip",
"nodejs-cpp_binary_http-domain",
"nodejs-cpp_binary_http-ip",
"nodejs-cpp_binary_http-ip-ssl",
@@ -331,6 +341,9 @@
"nodejs-cpp_json_http-domain",
"nodejs-cpp_json_http-ip",
"nodejs-cpp_json_http-ip-ssl",
+ "nodejs-cpp_header_http-ip",
+ "nodejs-cpp_header_http-ip-ssl",
+ "nodejs-cpp_header_http-domain",
"nodejs-d_binary_http-ip",
"nodejs-d_binary_http-ip-ssl",
"nodejs-d_compact_http-ip",
@@ -349,6 +362,7 @@
"nodejs-hs_binary_http-ip",
"nodejs-hs_compact_http-ip",
"nodejs-hs_json_http-ip",
+ "nodejs-hs_header_http-ip",
"nodejs-java_binary_http-ip",
"nodejs-java_binary_http-ip-ssl",
"nodejs-java_compact_http-ip",
@@ -369,6 +383,10 @@
"nodejs-py3_compact_http-ip-ssl",
"nodejs-py3_json_http-ip",
"nodejs-py3_json_http-ip-ssl",
+ "nodejs-py3_header_http-ip",
+ "nodejs-py3_header_http-ip-ssl",
+ "nodejs-py_header_http-ip",
+ "nodejs-py_header_http-ip-ssl",
"nodejs-py_binary-accel_http-ip",
"nodejs-py_binary-accel_http-ip-ssl",
"nodejs-py_binary_http-ip",
@@ -397,6 +415,38 @@
"py-cpp_header_http-ip-ssl",
"py-cpp_json_http-ip",
"py-cpp_json_http-ip-ssl",
+ "py-cpp_multi-binary_http-ip",
+ "py-cpp_multi-binary_http-ip-ssl",
+ "py-cpp_multi_http-ip",
+ "py-cpp_multi_http-ip-ssl",
+ "py-cpp_multia-binary_http-ip",
+ "py-cpp_multia-binary_http-ip-ssl",
+ "py-cpp_multia-binary_zlib-ip",
+ "py-cpp_multia-binary_zlib-ip-ssl",
+ "py-cpp_multia-multi_http-ip",
+ "py-cpp_multia-multi_http-ip-ssl",
+ "py-cpp_multia-multi_zlib-ip",
+ "py-cpp_multia-multi_zlib-ip-ssl",
+ "py-cpp_multiac-compact_http-ip",
+ "py-cpp_multiac-compact_http-ip-ssl",
+ "py-cpp_multiac-compact_zlib-ip",
+ "py-cpp_multiac-compact_zlib-ip-ssl",
+ "py-cpp_multiac-multic_http-ip",
+ "py-cpp_multiac-multic_http-ip-ssl",
+ "py-cpp_multiac-multic_zlib-ip",
+ "py-cpp_multiac-multic_zlib-ip-ssl",
+ "py-cpp_multic-compact_http-ip",
+ "py-cpp_multic-compact_http-ip-ssl",
+ "py-cpp_multic_http-ip",
+ "py-cpp_multic_http-ip-ssl",
+ "py-cpp_multih-header_http-ip",
+ "py-cpp_multih-header_http-ip-ssl",
+ "py-cpp_multih_http-ip",
+ "py-cpp_multih_http-ip-ssl",
+ "py-cpp_multij-json_http-ip",
+ "py-cpp_multij-json_http-ip-ssl",
+ "py-cpp_multij_http-ip",
+ "py-cpp_multij_http-ip-ssl",
"py-d_accel-binary_http-ip",
"py-d_accel-binary_http-ip-ssl",
"py-d_accelc-compact_http-ip",
@@ -418,21 +468,34 @@
"py-hs_compact_http-ip",
"py-hs_header_http-ip",
"py-hs_json_http-ip",
- "py-java_accel-binary_http-ip",
"py-java_accel-binary_http-ip-ssl",
- "py-java_accelc-compact_http-ip",
"py-java_accelc-compact_http-ip-ssl",
- "py-java_binary_http-ip",
"py-java_binary_http-ip-ssl",
- "py-java_compact_http-ip",
"py-java_compact_http-ip-ssl",
- "py-java_json_http-ip",
"py-java_json_http-ip-ssl",
+ "py-java_multi-binary_http-ip-ssl",
+ "py-java_multi_http-ip-ssl",
+ "py-java_multia-binary_http-ip-ssl",
+ "py-java_multia-multi_http-ip-ssl",
+ "py-java_multiac-compact_http-ip-ssl",
+ "py-java_multiac-multic_http-ip-ssl",
+ "py-java_multic-compact_http-ip-ssl",
+ "py-java_multic_http-ip-ssl",
+ "py-java_multij-json_http-ip-ssl",
+ "py-java_multij_http-ip-ssl",
"py-lua_accel-binary_http-ip",
"py-lua_accelc-compact_http-ip",
"py-lua_binary_http-ip",
"py-lua_compact_http-ip",
"py-lua_json_http-ip",
+ "py-rs_multi_buffered-ip",
+ "py-rs_multi_framed-ip",
+ "py-rs_multia-multi_buffered-ip",
+ "py-rs_multia-multi_framed-ip",
+ "py-rs_multiac-multic_buffered-ip",
+ "py-rs_multiac-multic_framed-ip",
+ "py-rs_multic_buffered-ip",
+ "py-rs_multic_framed-ip",
"py3-cpp_accel-binary_http-ip",
"py3-cpp_accel-binary_http-ip-ssl",
"py3-cpp_accel-binary_zlib-ip",
@@ -449,6 +512,38 @@
"py3-cpp_header_http-ip-ssl",
"py3-cpp_json_http-ip",
"py3-cpp_json_http-ip-ssl",
+ "py3-cpp_multi-binary_http-ip",
+ "py3-cpp_multi-binary_http-ip-ssl",
+ "py3-cpp_multi_http-ip",
+ "py3-cpp_multi_http-ip-ssl",
+ "py3-cpp_multia-binary_http-ip",
+ "py3-cpp_multia-binary_http-ip-ssl",
+ "py3-cpp_multia-binary_zlib-ip",
+ "py3-cpp_multia-binary_zlib-ip-ssl",
+ "py3-cpp_multia-multi_http-ip",
+ "py3-cpp_multia-multi_http-ip-ssl",
+ "py3-cpp_multia-multi_zlib-ip",
+ "py3-cpp_multia-multi_zlib-ip-ssl",
+ "py3-cpp_multiac-compact_http-ip",
+ "py3-cpp_multiac-compact_http-ip-ssl",
+ "py3-cpp_multiac-compact_zlib-ip",
+ "py3-cpp_multiac-compact_zlib-ip-ssl",
+ "py3-cpp_multiac-multic_http-ip",
+ "py3-cpp_multiac-multic_http-ip-ssl",
+ "py3-cpp_multiac-multic_zlib-ip",
+ "py3-cpp_multiac-multic_zlib-ip-ssl",
+ "py3-cpp_multic-compact_http-ip",
+ "py3-cpp_multic-compact_http-ip-ssl",
+ "py3-cpp_multic_http-ip",
+ "py3-cpp_multic_http-ip-ssl",
+ "py3-cpp_multih-header_http-ip",
+ "py3-cpp_multih-header_http-ip-ssl",
+ "py3-cpp_multih_http-ip",
+ "py3-cpp_multih_http-ip-ssl",
+ "py3-cpp_multij-json_http-ip",
+ "py3-cpp_multij-json_http-ip-ssl",
+ "py3-cpp_multij_http-ip",
+ "py3-cpp_multij_http-ip-ssl",
"py3-d_accel-binary_http-ip",
"py3-d_accel-binary_http-ip-ssl",
"py3-d_accelc-compact_http-ip",
@@ -470,25 +565,38 @@
"py3-hs_compact_http-ip",
"py3-hs_header_http-ip",
"py3-hs_json_http-ip",
- "py3-java_accel-binary_http-ip",
"py3-java_accel-binary_http-ip-ssl",
- "py3-java_accelc-compact_http-ip",
"py3-java_accelc-compact_http-ip-ssl",
- "py3-java_binary_http-ip",
"py3-java_binary_http-ip-ssl",
- "py3-java_compact_http-ip",
"py3-java_compact_http-ip-ssl",
- "py3-java_json_http-ip",
"py3-java_json_http-ip-ssl",
+ "py3-java_multi-binary_http-ip-ssl",
+ "py3-java_multi_http-ip-ssl",
+ "py3-java_multia-binary_http-ip-ssl",
+ "py3-java_multia-multi_http-ip-ssl",
+ "py3-java_multiac-compact_http-ip-ssl",
+ "py3-java_multiac-multic_http-ip-ssl",
+ "py3-java_multic-compact_http-ip-ssl",
+ "py3-java_multic_http-ip-ssl",
+ "py3-java_multij-json_http-ip-ssl",
+ "py3-java_multij_http-ip-ssl",
"py3-lua_accel-binary_http-ip",
"py3-lua_accelc-compact_http-ip",
"py3-lua_binary_http-ip",
"py3-lua_compact_http-ip",
"py3-lua_json_http-ip",
+ "py3-rs_multi_buffered-ip",
+ "py3-rs_multi_framed-ip",
+ "py3-rs_multia-multi_buffered-ip",
+ "py3-rs_multia-multi_framed-ip",
+ "py3-rs_multiac-multic_buffered-ip",
+ "py3-rs_multiac-multic_framed-ip",
+ "py3-rs_multic_buffered-ip",
+ "py3-rs_multic_framed-ip",
"rb-cpp_json_buffered-domain",
"rb-cpp_json_buffered-ip",
"rb-cpp_json_buffered-ip-ssl",
"rb-cpp_json_framed-domain",
"rb-cpp_json_framed-ip",
"rb-cpp_json_framed-ip-ssl"
-]
\ No newline at end of file
+]
diff --git a/test/lua/Makefile.am b/test/lua/Makefile.am
index ed8c5ae..b2683e1 100644
--- a/test/lua/Makefile.am
+++ b/test/lua/Makefile.am
@@ -28,4 +28,7 @@
precross: stubs
clean-local:
- $(RM) -r gen-lua
+ $(RM) -r gen-lua/
+
+dist-hook:
+ $(RM) -r $(distdir)/gen-lua/
diff --git a/test/netcore/Makefile.am b/test/netcore/Makefile.am
index 376ffb7..2fff4ba 100644
--- a/test/netcore/Makefile.am
+++ b/test/netcore/Makefile.am
@@ -27,10 +27,19 @@
clean-local:
$(RM) -r Client/bin
- $(RM) -r Server/bin
$(RM) -r Client/obj
+ $(RM) -r Client/ThriftTest
+ $(RM) -r Server/bin
$(RM) -r Server/obj
- $(RM) -r ThriftTest/ThriftTest
+ $(RM) -r Server/ThriftTest
+
+dist-hook:
+ $(RM) -r $(distdir)/Client/bin
+ $(RM) -r $(distdir)/Client/obj
+ $(RM) -r $(distdir)/Client/ThriftTest
+ $(RM) -r $(distdir)/Server/bin
+ $(RM) -r $(distdir)/Server/obj
+ $(RM) -r $(distdir)/Server/ThriftTest
EXTRA_DIST = \
Client \
diff --git a/test/netstd/Client/.gitignore b/test/netstd/Client/.gitignore
new file mode 100644
index 0000000..67d5510
--- /dev/null
+++ b/test/netstd/Client/.gitignore
@@ -0,0 +1,2 @@
+# ignore for autogenerated files
+/ThriftTest
diff --git a/test/netstd/Client/Client.csproj b/test/netstd/Client/Client.csproj
new file mode 100644
index 0000000..ed30c30
--- /dev/null
+++ b/test/netstd/Client/Client.csproj
@@ -0,0 +1,50 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <!--
+ 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.
+ -->
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ <AssemblyName>Client</AssemblyName>
+ <PackageId>Client</PackageId>
+ <OutputType>Exe</OutputType>
+ <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
+ <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+ <ItemGroup>
+ <PackageReference Include="System.Net.Http.WinHttpHandler" Version="4.5.2" />
+ <PackageReference Include="System.Runtime.Serialization.Primitives" Version="[4.3,)" />
+ <PackageReference Include="System.ServiceModel.Primitives" Version="4.5.3" />
+ <PackageReference Include="System.Threading" Version="[4.3,)" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\lib\netstd\Thrift\Thrift.csproj" />
+ </ItemGroup>
+ <Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
+ <Exec Condition="'$(OS)' == 'Windows_NT'" Command="where thrift" ConsoleToMSBuild="true">
+ <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" />
+ </Exec>
+ <Exec Condition="Exists('$(PathToThrift)')" Command=""$(PathToThrift)" -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../ThriftTest.thrift" />
+ <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../ThriftTest.thrift" />
+ <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../ThriftTest.thrift" />
+ </Target>
+</Project>
diff --git a/test/netstd/Client/Program.cs b/test/netstd/Client/Program.cs
new file mode 100644
index 0000000..8d973c4
--- /dev/null
+++ b/test/netstd/Client/Program.cs
@@ -0,0 +1,73 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using ThriftTest;
+
+namespace Client
+{
+ public class Program
+ {
+ public static int Main(string[] args)
+ {
+ try
+ {
+ Console.SetBufferSize(Console.BufferWidth, 4096);
+ }
+ catch (Exception)
+ {
+ Console.WriteLine("Failed to grow scroll-back buffer");
+ }
+
+ // split mode and options
+ var subArgs = new List<string>(args);
+ var firstArg = string.Empty;
+ if (subArgs.Count > 0)
+ {
+ firstArg = subArgs[0];
+ subArgs.RemoveAt(0);
+ }
+
+ // run whatever mode is choosen
+ switch(firstArg)
+ {
+ case "client":
+ return TestClient.Execute(subArgs);
+ case "--help":
+ PrintHelp();
+ return 0;
+ default:
+ Console.WriteLine("Invalid argument: {0}", firstArg);
+ PrintHelp();
+ return -1;
+ }
+ }
+
+ private static void PrintHelp()
+ {
+ Console.WriteLine("Usage:");
+ Console.WriteLine(" Client client [options]'");
+ Console.WriteLine(" Client --help");
+ Console.WriteLine("");
+
+ TestClient.PrintOptionsHelp();
+ }
+ }
+}
+
+
diff --git a/test/netstd/Client/Properties/AssemblyInfo.cs b/test/netstd/Client/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..157152b
--- /dev/null
+++ b/test/netstd/Client/Properties/AssemblyInfo.cs
@@ -0,0 +1,43 @@
+// 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.
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("Client")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("B0C13DA0-3117-4844-8AE8-B1775E46223D")]
+
diff --git a/test/netstd/Client/TestClient.cs b/test/netstd/Client/TestClient.cs
new file mode 100644
index 0000000..ddc36ac
--- /dev/null
+++ b/test/netstd/Client/TestClient.cs
@@ -0,0 +1,1020 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Reflection;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+using System.ServiceModel;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Thrift.Collections;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+
+namespace ThriftTest
+{
+ internal enum ProtocolChoice
+ {
+ Binary,
+ Compact,
+ Json
+ }
+
+ // it does not make much sense to use buffered when we already use framed
+ internal enum LayeredChoice
+ {
+ None,
+ Buffered,
+ Framed
+ }
+
+
+ internal enum TransportChoice
+ {
+ Socket,
+ TlsSocket,
+ NamedPipe
+ }
+
+ public class TestClient
+ {
+ private class TestParams
+ {
+ public int numIterations = 1;
+ public string host = "localhost";
+ public int port = 9090;
+ public int numThreads = 1;
+ public string url;
+ public string pipe;
+ public LayeredChoice layered = LayeredChoice.None;
+ public ProtocolChoice protocol = ProtocolChoice.Binary;
+ public TransportChoice transport = TransportChoice.Socket;
+
+ internal void Parse( List<string> args)
+ {
+ for (var i = 0; i < args.Count; ++i)
+ {
+ if (args[i] == "-u")
+ {
+ url = args[++i];
+ }
+ else if (args[i] == "-n")
+ {
+ numIterations = Convert.ToInt32(args[++i]);
+ }
+ else if (args[i].StartsWith("--pipe="))
+ {
+ pipe = args[i].Substring(args[i].IndexOf("=") + 1);
+ transport = TransportChoice.NamedPipe;
+ }
+ else if (args[i].StartsWith("--host="))
+ {
+ // check there for ipaddress
+ host = args[i].Substring(args[i].IndexOf("=") + 1);
+ if (transport != TransportChoice.TlsSocket)
+ transport = TransportChoice.Socket;
+ }
+ else if (args[i].StartsWith("--port="))
+ {
+ port = int.Parse(args[i].Substring(args[i].IndexOf("=") + 1));
+ if (transport != TransportChoice.TlsSocket)
+ transport = TransportChoice.Socket;
+ }
+ else if (args[i] == "-b" || args[i] == "--buffered" || args[i] == "--transport=buffered")
+ {
+ layered = LayeredChoice.Buffered;
+ }
+ else if (args[i] == "-f" || args[i] == "--framed" || args[i] == "--transport=framed")
+ {
+ layered = LayeredChoice.Framed;
+ }
+ else if (args[i] == "-t")
+ {
+ numThreads = Convert.ToInt32(args[++i]);
+ }
+ else if (args[i] == "--binary" || args[i] == "--protocol=binary")
+ {
+ protocol = ProtocolChoice.Binary;
+ }
+ else if (args[i] == "--compact" || args[i] == "--protocol=compact")
+ {
+ protocol = ProtocolChoice.Compact;
+ }
+ else if (args[i] == "--json" || args[i] == "--protocol=json")
+ {
+ protocol = ProtocolChoice.Json;
+ }
+ else if (args[i] == "--ssl")
+ {
+ transport = TransportChoice.TlsSocket;
+ }
+ else if (args[i] == "--help")
+ {
+ PrintOptionsHelp();
+ return;
+ }
+ else
+ {
+ Console.WriteLine("Invalid argument: {0}", args[i]);
+ PrintOptionsHelp();
+ return;
+ }
+ }
+
+ switch (transport)
+ {
+ case TransportChoice.Socket:
+ Console.WriteLine("Using socket transport");
+ break;
+ case TransportChoice.TlsSocket:
+ Console.WriteLine("Using encrypted transport");
+ break;
+ case TransportChoice.NamedPipe:
+ Console.WriteLine("Using named pipes transport");
+ break;
+ default: // unhandled case
+ Debug.Assert(false);
+ break;
+ }
+
+ switch (layered)
+ {
+ case LayeredChoice.Framed:
+ Console.WriteLine("Using framed transport");
+ break;
+ case LayeredChoice.Buffered:
+ Console.WriteLine("Using buffered transport");
+ break;
+ default: // unhandled case?
+ Debug.Assert(layered == LayeredChoice.None);
+ break;
+ }
+
+ switch (protocol)
+ {
+ case ProtocolChoice.Binary:
+ Console.WriteLine("Using binary protocol");
+ break;
+ case ProtocolChoice.Compact:
+ Console.WriteLine("Using compact protocol");
+ break;
+ case ProtocolChoice.Json:
+ Console.WriteLine("Using JSON protocol");
+ break;
+ default: // unhandled case?
+ Debug.Assert(false);
+ break;
+ }
+ }
+
+ private static X509Certificate2 GetClientCert()
+ {
+ var clientCertName = "client.p12";
+ var possiblePaths = new List<string>
+ {
+ "../../../keys/",
+ "../../keys/",
+ "../keys/",
+ "keys/",
+ };
+
+ string existingPath = null;
+ foreach (var possiblePath in possiblePaths)
+ {
+ var path = Path.GetFullPath(possiblePath + clientCertName);
+ if (File.Exists(path))
+ {
+ existingPath = path;
+ break;
+ }
+ }
+
+ if (string.IsNullOrEmpty(existingPath))
+ {
+ throw new FileNotFoundException($"Cannot find file: {clientCertName}");
+ }
+
+ var cert = new X509Certificate2(existingPath, "thrift");
+
+ return cert;
+ }
+
+ public TTransport CreateTransport()
+ {
+ if (url == null)
+ {
+ // endpoint transport
+ TTransport trans = null;
+
+ switch(transport)
+ {
+ case TransportChoice.NamedPipe:
+ Debug.Assert(pipe != null);
+ trans = new TNamedPipeTransport(pipe);
+ break;
+
+ case TransportChoice.TlsSocket:
+ var cert = GetClientCert();
+ if (cert == null || !cert.HasPrivateKey)
+ {
+ throw new InvalidOperationException("Certificate doesn't contain private key");
+ }
+
+ trans = new TTlsSocketTransport(host, port, 0, cert,
+ (sender, certificate, chain, errors) => true,
+ null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12);
+ break;
+
+ case TransportChoice.Socket:
+ default:
+ trans = new TSocketTransport(host, port);
+ break;
+ }
+
+
+ // layered transport
+ switch(layered)
+ {
+ case LayeredChoice.Buffered:
+ trans = new TBufferedTransport(trans);
+ break;
+ case LayeredChoice.Framed:
+ trans = new TFramedTransport(trans);
+ break;
+ default:
+ Debug.Assert(layered == LayeredChoice.None);
+ break;
+ }
+
+ return trans;
+ }
+
+ return new THttpTransport(new Uri(url), null);
+ }
+
+ public TProtocol CreateProtocol(TTransport transport)
+ {
+ switch (protocol)
+ {
+ case ProtocolChoice.Compact:
+ return new TCompactProtocol(transport);
+ case ProtocolChoice.Json:
+ return new TJsonProtocol(transport);
+ case ProtocolChoice.Binary:
+ default:
+ return new TBinaryProtocol(transport);
+ }
+ }
+ }
+
+
+ private const int ErrorBaseTypes = 1;
+ private const int ErrorStructs = 2;
+ private const int ErrorContainers = 4;
+ private const int ErrorExceptions = 8;
+ private const int ErrorUnknown = 64;
+
+ private class ClientTest
+ {
+ private readonly TTransport transport;
+ private readonly ThriftTest.Client client;
+ private readonly int numIterations;
+ private bool done;
+
+ public int ReturnCode { get; set; }
+
+ public ClientTest(TestParams param)
+ {
+ transport = param.CreateTransport();
+ client = new ThriftTest.Client(param.CreateProtocol(transport));
+ numIterations = param.numIterations;
+ }
+
+ public void Execute()
+ {
+ if (done)
+ {
+ Console.WriteLine("Execute called more than once");
+ throw new InvalidOperationException();
+ }
+
+ for (var i = 0; i < numIterations; i++)
+ {
+ try
+ {
+ if (!transport.IsOpen)
+ transport.OpenAsync(MakeTimeoutToken()).GetAwaiter().GetResult();
+ }
+ catch (TTransportException ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ Console.WriteLine("Connect failed: " + ex.Message);
+ ReturnCode |= ErrorUnknown;
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ continue;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ Console.WriteLine("Connect failed: " + ex.Message);
+ ReturnCode |= ErrorUnknown;
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ continue;
+ }
+
+ try
+ {
+ ReturnCode |= ExecuteClientTestAsync(client).GetAwaiter().GetResult(); ;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ ReturnCode |= ErrorUnknown;
+ }
+ }
+ try
+ {
+ transport.Close();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Error while closing transport");
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ }
+ done = true;
+ }
+ }
+
+ internal static void PrintOptionsHelp()
+ {
+ Console.WriteLine("Client options:");
+ Console.WriteLine(" -u <URL>");
+ Console.WriteLine(" -t <# of threads to run> default = 1");
+ Console.WriteLine(" -n <# of iterations> per thread");
+ Console.WriteLine(" --pipe=<pipe name>");
+ Console.WriteLine(" --host=<IP address>");
+ Console.WriteLine(" --port=<port number>");
+ Console.WriteLine(" --transport=<transport name> one of buffered,framed (defaults to none)");
+ Console.WriteLine(" --protocol=<protocol name> one of compact,json (defaults to binary)");
+ Console.WriteLine(" --ssl");
+ Console.WriteLine();
+ }
+
+ public static int Execute(List<string> args)
+ {
+ try
+ {
+ var param = new TestParams();
+
+ try
+ {
+ param.Parse(args);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ Console.WriteLine("Error while parsing arguments");
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ return ErrorUnknown;
+ }
+
+ var tests = Enumerable.Range(0, param.numThreads).Select(_ => new ClientTest(param)).ToArray();
+
+ //issue tests on separate threads simultaneously
+ var threads = tests.Select(test => new Task(test.Execute)).ToArray();
+ var start = DateTime.Now;
+ foreach (var t in threads)
+ {
+ t.Start();
+ }
+
+ Task.WaitAll(threads);
+
+ Console.WriteLine("Total time: " + (DateTime.Now - start));
+ Console.WriteLine();
+ return tests.Select(t => t.ReturnCode).Aggregate((r1, r2) => r1 | r2);
+ }
+ catch (Exception outerEx)
+ {
+ Console.WriteLine("*** FAILED ***");
+ Console.WriteLine("Unexpected error");
+ Console.WriteLine(outerEx.Message + " ST: " + outerEx.StackTrace);
+ return ErrorUnknown;
+ }
+ }
+
+ public static string BytesToHex(byte[] data)
+ {
+ return BitConverter.ToString(data).Replace("-", string.Empty);
+ }
+
+ public static byte[] PrepareTestData(bool randomDist)
+ {
+ var retval = new byte[0x100];
+ var initLen = Math.Min(0x100, retval.Length);
+
+ // linear distribution, unless random is requested
+ if (!randomDist)
+ {
+ for (var i = 0; i < initLen; ++i)
+ {
+ retval[i] = (byte)i;
+ }
+ return retval;
+ }
+
+ // random distribution
+ for (var i = 0; i < initLen; ++i)
+ {
+ retval[i] = (byte)0;
+ }
+ var rnd = new Random();
+ for (var i = 1; i < initLen; ++i)
+ {
+ while (true)
+ {
+ var nextPos = rnd.Next() % initLen;
+ if (retval[nextPos] == 0)
+ {
+ retval[nextPos] = (byte)i;
+ break;
+ }
+ }
+ }
+ return retval;
+ }
+
+ private static CancellationToken MakeTimeoutToken(int msec = 5000)
+ {
+ var token = new CancellationTokenSource(msec);
+ return token.Token;
+ }
+
+ public static async Task<int> ExecuteClientTestAsync(ThriftTest.Client client)
+ {
+ var returnCode = 0;
+
+ Console.Write("testVoid()");
+ await client.testVoidAsync(MakeTimeoutToken());
+ Console.WriteLine(" = void");
+
+ Console.Write("testString(\"Test\")");
+ var s = await client.testStringAsync("Test", MakeTimeoutToken());
+ Console.WriteLine(" = \"" + s + "\"");
+ if ("Test" != s)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+
+ Console.Write("testBool(true)");
+ var t = await client.testBoolAsync((bool)true, MakeTimeoutToken());
+ Console.WriteLine(" = " + t);
+ if (!t)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+ Console.Write("testBool(false)");
+ var f = await client.testBoolAsync((bool)false, MakeTimeoutToken());
+ Console.WriteLine(" = " + f);
+ if (f)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+
+ Console.Write("testByte(1)");
+ var i8 = await client.testByteAsync((sbyte)1, MakeTimeoutToken());
+ Console.WriteLine(" = " + i8);
+ if (1 != i8)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+
+ Console.Write("testI32(-1)");
+ var i32 = await client.testI32Async(-1, MakeTimeoutToken());
+ Console.WriteLine(" = " + i32);
+ if (-1 != i32)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+
+ Console.Write("testI64(-34359738368)");
+ var i64 = await client.testI64Async(-34359738368, MakeTimeoutToken());
+ Console.WriteLine(" = " + i64);
+ if (-34359738368 != i64)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+
+ // TODO: Validate received message
+ Console.Write("testDouble(5.325098235)");
+ var dub = await client.testDoubleAsync(5.325098235, MakeTimeoutToken());
+ Console.WriteLine(" = " + dub);
+ if (5.325098235 != dub)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+ Console.Write("testDouble(-0.000341012439638598279)");
+ dub = await client.testDoubleAsync(-0.000341012439638598279, MakeTimeoutToken());
+ Console.WriteLine(" = " + dub);
+ if (-0.000341012439638598279 != dub)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+
+ var binOut = PrepareTestData(true);
+ Console.Write("testBinary(" + BytesToHex(binOut) + ")");
+ try
+ {
+ var binIn = await client.testBinaryAsync(binOut, MakeTimeoutToken());
+ Console.WriteLine(" = " + BytesToHex(binIn));
+ if (binIn.Length != binOut.Length)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+ for (var ofs = 0; ofs < Math.Min(binIn.Length, binOut.Length); ++ofs)
+ if (binIn[ofs] != binOut[ofs])
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+ }
+ catch (Thrift.TApplicationException ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ }
+
+ // binary equals?
+ Console.WriteLine("Test CrazyNesting");
+ var one = new CrazyNesting();
+ var two = new CrazyNesting();
+ one.String_field = "crazy";
+ two.String_field = "crazy";
+ one.Binary_field = new byte[] { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF };
+ two.Binary_field = new byte[10] { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF };
+ if (typeof(CrazyNesting).GetMethod("Equals")?.DeclaringType == typeof(CrazyNesting))
+ {
+ if (!one.Equals(two))
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorContainers;
+ throw new Exception("CrazyNesting.Equals failed");
+ }
+ }
+
+ // TODO: Validate received message
+ Console.Write("testStruct({\"Zero\", 1, -3, -5})");
+ var o = new Xtruct();
+ o.String_thing = "Zero";
+ o.Byte_thing = (sbyte)1;
+ o.I32_thing = -3;
+ o.I64_thing = -5;
+ var i = await client.testStructAsync(o, MakeTimeoutToken());
+ Console.WriteLine(" = {\"" + i.String_thing + "\", " + i.Byte_thing + ", " + i.I32_thing + ", " + i.I64_thing + "}");
+
+ // TODO: Validate received message
+ Console.Write("testNest({1, {\"Zero\", 1, -3, -5}, 5})");
+ var o2 = new Xtruct2();
+ o2.Byte_thing = (sbyte)1;
+ o2.Struct_thing = o;
+ o2.I32_thing = 5;
+ var i2 = await client.testNestAsync(o2, MakeTimeoutToken());
+ i = i2.Struct_thing;
+ Console.WriteLine(" = {" + i2.Byte_thing + ", {\"" + i.String_thing + "\", " + i.Byte_thing + ", " + i.I32_thing + ", " + i.I64_thing + "}, " + i2.I32_thing + "}");
+
+ var mapout = new Dictionary<int, int>();
+ for (var j = 0; j < 5; j++)
+ {
+ mapout[j] = j - 10;
+ }
+ Console.Write("testMap({");
+ var first = true;
+ foreach (var key in mapout.Keys)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ Console.Write(", ");
+ }
+ Console.Write(key + " => " + mapout[key]);
+ }
+ Console.Write("})");
+
+ var mapin = await client.testMapAsync(mapout, MakeTimeoutToken());
+
+ Console.Write(" = {");
+ first = true;
+ foreach (var key in mapin.Keys)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ Console.Write(", ");
+ }
+ Console.Write(key + " => " + mapin[key]);
+ }
+ Console.WriteLine("}");
+
+ // TODO: Validate received message
+ var listout = new List<int>();
+ for (var j = -2; j < 3; j++)
+ {
+ listout.Add(j);
+ }
+ Console.Write("testList({");
+ first = true;
+ foreach (var j in listout)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ Console.Write(", ");
+ }
+ Console.Write(j);
+ }
+ Console.Write("})");
+
+ var listin = await client.testListAsync(listout, MakeTimeoutToken());
+
+ Console.Write(" = {");
+ first = true;
+ foreach (var j in listin)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ Console.Write(", ");
+ }
+ Console.Write(j);
+ }
+ Console.WriteLine("}");
+
+ //set
+ // TODO: Validate received message
+ var setout = new THashSet<int>();
+ for (var j = -2; j < 3; j++)
+ {
+ setout.Add(j);
+ }
+ Console.Write("testSet({");
+ first = true;
+ foreach (int j in setout)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ Console.Write(", ");
+ }
+ Console.Write(j);
+ }
+ Console.Write("})");
+
+ var setin = await client.testSetAsync(setout, MakeTimeoutToken());
+
+ Console.Write(" = {");
+ first = true;
+ foreach (int j in setin)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ Console.Write(", ");
+ }
+ Console.Write(j);
+ }
+ Console.WriteLine("}");
+
+
+ Console.Write("testEnum(ONE)");
+ var ret = await client.testEnumAsync(Numberz.ONE, MakeTimeoutToken());
+ Console.WriteLine(" = " + ret);
+ if (Numberz.ONE != ret)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorStructs;
+ }
+
+ Console.Write("testEnum(TWO)");
+ ret = await client.testEnumAsync(Numberz.TWO, MakeTimeoutToken());
+ Console.WriteLine(" = " + ret);
+ if (Numberz.TWO != ret)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorStructs;
+ }
+
+ Console.Write("testEnum(THREE)");
+ ret = await client.testEnumAsync(Numberz.THREE, MakeTimeoutToken());
+ Console.WriteLine(" = " + ret);
+ if (Numberz.THREE != ret)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorStructs;
+ }
+
+ Console.Write("testEnum(FIVE)");
+ ret = await client.testEnumAsync(Numberz.FIVE, MakeTimeoutToken());
+ Console.WriteLine(" = " + ret);
+ if (Numberz.FIVE != ret)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorStructs;
+ }
+
+ Console.Write("testEnum(EIGHT)");
+ ret = await client.testEnumAsync(Numberz.EIGHT, MakeTimeoutToken());
+ Console.WriteLine(" = " + ret);
+ if (Numberz.EIGHT != ret)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorStructs;
+ }
+
+ Console.Write("testTypedef(309858235082523)");
+ var uid = await client.testTypedefAsync(309858235082523L, MakeTimeoutToken());
+ Console.WriteLine(" = " + uid);
+ if (309858235082523L != uid)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorStructs;
+ }
+
+ // TODO: Validate received message
+ Console.Write("testMapMap(1)");
+ var mm = await client.testMapMapAsync(1, MakeTimeoutToken());
+ Console.Write(" = {");
+ foreach (var key in mm.Keys)
+ {
+ Console.Write(key + " => {");
+ var m2 = mm[key];
+ foreach (var k2 in m2.Keys)
+ {
+ Console.Write(k2 + " => " + m2[k2] + ", ");
+ }
+ Console.Write("}, ");
+ }
+ Console.WriteLine("}");
+
+ // TODO: Validate received message
+ var insane = new Insanity();
+ insane.UserMap = new Dictionary<Numberz, long>();
+ insane.UserMap[Numberz.FIVE] = 5000L;
+ var truck = new Xtruct();
+ truck.String_thing = "Truck";
+ truck.Byte_thing = (sbyte)8;
+ truck.I32_thing = 8;
+ truck.I64_thing = 8;
+ insane.Xtructs = new List<Xtruct>();
+ insane.Xtructs.Add(truck);
+ Console.Write("testInsanity()");
+ var whoa = await client.testInsanityAsync(insane, MakeTimeoutToken());
+ Console.Write(" = {");
+ foreach (var key in whoa.Keys)
+ {
+ var val = whoa[key];
+ Console.Write(key + " => {");
+
+ foreach (var k2 in val.Keys)
+ {
+ var v2 = val[k2];
+
+ Console.Write(k2 + " => {");
+ var userMap = v2.UserMap;
+
+ Console.Write("{");
+ if (userMap != null)
+ {
+ foreach (var k3 in userMap.Keys)
+ {
+ Console.Write(k3 + " => " + userMap[k3] + ", ");
+ }
+ }
+ else
+ {
+ Console.Write("null");
+ }
+ Console.Write("}, ");
+
+ var xtructs = v2.Xtructs;
+
+ Console.Write("{");
+ if (xtructs != null)
+ {
+ foreach (var x in xtructs)
+ {
+ Console.Write("{\"" + x.String_thing + "\", " + x.Byte_thing + ", " + x.I32_thing + ", " + x.I32_thing + "}, ");
+ }
+ }
+ else
+ {
+ Console.Write("null");
+ }
+ Console.Write("}");
+
+ Console.Write("}, ");
+ }
+ Console.Write("}, ");
+ }
+ Console.WriteLine("}");
+
+ sbyte arg0 = 1;
+ var arg1 = 2;
+ var arg2 = long.MaxValue;
+ var multiDict = new Dictionary<short, string>();
+ multiDict[1] = "one";
+
+ var tmpMultiDict = new List<string>();
+ foreach (var pair in multiDict)
+ tmpMultiDict.Add(pair.Key +" => "+ pair.Value);
+
+ var arg4 = Numberz.FIVE;
+ long arg5 = 5000000;
+ Console.Write("Test Multi(" + arg0 + "," + arg1 + "," + arg2 + ",{" + string.Join(",", tmpMultiDict) + "}," + arg4 + "," + arg5 + ")");
+ var multiResponse = await client.testMultiAsync(arg0, arg1, arg2, multiDict, arg4, arg5, MakeTimeoutToken());
+ Console.Write(" = Xtruct(byte_thing:" + multiResponse.Byte_thing + ",String_thing:" + multiResponse.String_thing
+ + ",i32_thing:" + multiResponse.I32_thing + ",i64_thing:" + multiResponse.I64_thing + ")\n");
+
+ try
+ {
+ Console.WriteLine("testException(\"Xception\")");
+ await client.testExceptionAsync("Xception", MakeTimeoutToken());
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ }
+ catch (Xception ex)
+ {
+ if (ex.ErrorCode != 1001 || ex.Message != "Xception")
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ }
+ try
+ {
+ Console.WriteLine("testException(\"TException\")");
+ await client.testExceptionAsync("TException", MakeTimeoutToken());
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ }
+ catch (Thrift.TException)
+ {
+ // OK
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ }
+ try
+ {
+ Console.WriteLine("testException(\"ok\")");
+ await client.testExceptionAsync("ok", MakeTimeoutToken());
+ // OK
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ }
+
+ try
+ {
+ Console.WriteLine("testMultiException(\"Xception\", ...)");
+ await client.testMultiExceptionAsync("Xception", "ignore", MakeTimeoutToken());
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ }
+ catch (Xception ex)
+ {
+ if (ex.ErrorCode != 1001 || ex.Message != "This is an Xception")
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ }
+ try
+ {
+ Console.WriteLine("testMultiException(\"Xception2\", ...)");
+ await client.testMultiExceptionAsync("Xception2", "ignore", MakeTimeoutToken());
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ }
+ catch (Xception2 ex)
+ {
+ if (ex.ErrorCode != 2002 || ex.Struct_thing.String_thing != "This is an Xception2")
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ }
+ try
+ {
+ Console.WriteLine("testMultiException(\"success\", \"OK\")");
+ if ("OK" != (await client.testMultiExceptionAsync("success", "OK", MakeTimeoutToken())).String_thing)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorExceptions;
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ }
+
+ Console.WriteLine("Test Oneway(1)");
+ var sw = new Stopwatch();
+ sw.Start();
+ await client.testOnewayAsync(1, MakeTimeoutToken());
+ sw.Stop();
+ if (sw.ElapsedMilliseconds > 1000)
+ {
+ Console.WriteLine("*** FAILED ***");
+ returnCode |= ErrorBaseTypes;
+ }
+
+ Console.Write("Test Calltime()");
+ var times = 50;
+ sw.Reset();
+ sw.Start();
+ var token = MakeTimeoutToken(20000);
+ for (var k = 0; k < times; ++k)
+ await client.testVoidAsync(token);
+ sw.Stop();
+ Console.WriteLine(" = {0} ms a testVoid() call", sw.ElapsedMilliseconds / times);
+ return returnCode;
+ }
+ }
+}
diff --git a/compiler/cpp/test/cpp_plugin_test.sh b/test/netstd/Makefile.am
old mode 100755
new mode 100644
similarity index 71%
rename from compiler/cpp/test/cpp_plugin_test.sh
rename to test/netstd/Makefile.am
index ddb2e0a..376ffb7
--- a/compiler/cpp/test/cpp_plugin_test.sh
+++ b/test/netstd/Makefile.am
@@ -1,5 +1,3 @@
-#!/bin/sh
-
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -19,9 +17,25 @@
# under the License.
#
-# this file is intended to be invoked by make.
-set -e
-mkdir -p gen-cpp gen-mycpp
-PATH=.:"$PATH" ../thrift -r -out gen-cpp -gen cpp ../../../test/Include.thrift
-PATH=.:"$PATH" ../thrift -r -out gen-mycpp -gen mycpp ../../../test/Include.thrift
-diff -urN gen-cpp gen-mycpp
+SUBDIRS = .
+
+all-local:
+ $(DOTNETCORE) build
+
+precross:
+ $(DOTNETCORE) build
+
+clean-local:
+ $(RM) -r Client/bin
+ $(RM) -r Server/bin
+ $(RM) -r Client/obj
+ $(RM) -r Server/obj
+ $(RM) -r ThriftTest/ThriftTest
+
+EXTRA_DIST = \
+ Client \
+ README.md \
+ Server \
+ ThriftTest.sln \
+ build.cmd \
+ build.sh
diff --git a/test/netstd/README.md b/test/netstd/README.md
new file mode 100644
index 0000000..ed728d1
--- /dev/null
+++ b/test/netstd/README.md
@@ -0,0 +1,20 @@
+# Apache Thrift net-core-lib tests
+
+Tests for Thrift client library ported to Microsoft .Net Core
+
+# Content
+- ThriftTest - tests for Thrift library
+
+# Reused components
+- NET Core Standard 1.6 (SDK 2.0.0)
+
+# How to build on Windows
+- Get Thrift IDL compiler executable, add to some folder and add path to this folder into PATH variable
+- Open ThriftTest.sln in Visual Studio and build
+or
+- Build with scripts
+
+# How to build on Unix
+- Ensure you have .NET Core 2.0.0 SDK installed or use the Ubuntu Xenial docker image
+- Follow common build practice for Thrift: bootstrap, configure, and make precross
+
diff --git a/test/netstd/Server/.gitignore b/test/netstd/Server/.gitignore
new file mode 100644
index 0000000..67d5510
--- /dev/null
+++ b/test/netstd/Server/.gitignore
@@ -0,0 +1,2 @@
+# ignore for autogenerated files
+/ThriftTest
diff --git a/test/netstd/Server/Program.cs b/test/netstd/Server/Program.cs
new file mode 100644
index 0000000..8bfa371
--- /dev/null
+++ b/test/netstd/Server/Program.cs
@@ -0,0 +1,73 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using ThriftTest;
+
+namespace Server
+{
+ public class Program
+ {
+ public static int Main(string[] args)
+ {
+ try
+ {
+ Console.SetBufferSize(Console.BufferWidth, 4096);
+ }
+ catch (Exception)
+ {
+ Console.WriteLine("Failed to grow scroll-back buffer");
+ }
+
+ // split mode and options
+ var subArgs = new List<string>(args);
+ var firstArg = string.Empty;
+ if (subArgs.Count > 0)
+ {
+ firstArg = subArgs[0];
+ subArgs.RemoveAt(0);
+ }
+
+ // run whatever mode is choosen
+ switch(firstArg)
+ {
+ case "server":
+ return TestServer.Execute(subArgs);
+ case "--help":
+ PrintHelp();
+ return 0;
+ default:
+ Console.WriteLine("Invalid argument: {0}", firstArg);
+ PrintHelp();
+ return -1;
+ }
+ }
+
+ private static void PrintHelp()
+ {
+ Console.WriteLine("Usage:");
+ Console.WriteLine(" Server server [options]'");
+ Console.WriteLine(" Server --help");
+ Console.WriteLine("");
+
+ ServerParam.PrintOptionsHelp();
+ }
+ }
+}
+
+
diff --git a/test/netstd/Server/Properties/AssemblyInfo.cs b/test/netstd/Server/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..265495c
--- /dev/null
+++ b/test/netstd/Server/Properties/AssemblyInfo.cs
@@ -0,0 +1,43 @@
+// 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.
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("Server")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("B0C13DA0-3117-4844-8AE8-B1775E46223D")]
+
diff --git a/test/netstd/Server/Server.csproj b/test/netstd/Server/Server.csproj
new file mode 100644
index 0000000..44f46c9
--- /dev/null
+++ b/test/netstd/Server/Server.csproj
@@ -0,0 +1,52 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <!--
+ 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.
+ -->
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ <AssemblyName>Server</AssemblyName>
+ <PackageId>Server</PackageId>
+ <OutputType>Exe</OutputType>
+ <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
+ <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+ <ItemGroup>
+ <PackageReference Include="System.IO.Pipes" Version="4.3.0" />
+ <PackageReference Include="System.IO.Pipes.AccessControl" Version="4.5.1" />
+ <PackageReference Include="System.Net.Http.WinHttpHandler" Version="4.5.2" />
+ <PackageReference Include="System.Runtime.Serialization.Primitives" Version="[4.3,)" />
+ <PackageReference Include="System.ServiceModel.Primitives" Version="4.5.3" />
+ <PackageReference Include="System.Threading" Version="[4.3,)" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\lib\netstd\Thrift\Thrift.csproj" />
+ </ItemGroup>
+ <Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
+ <Exec Condition="'$(OS)' == 'Windows_NT'" Command="where thrift" ConsoleToMSBuild="true">
+ <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" />
+ </Exec>
+ <Exec Condition="Exists('$(PathToThrift)')" Command=""$(PathToThrift)" -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../ThriftTest.thrift" />
+ <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../ThriftTest.thrift" />
+ <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../ThriftTest.thrift" />
+ </Target>
+</Project>
\ No newline at end of file
diff --git a/test/netstd/Server/TestServer.cs b/test/netstd/Server/TestServer.cs
new file mode 100644
index 0000000..82b36eb
--- /dev/null
+++ b/test/netstd/Server/TestServer.cs
@@ -0,0 +1,643 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Thrift;
+using Thrift.Collections;
+using Thrift.Processor;
+using Thrift.Protocol;
+using Thrift.Server;
+using Thrift.Transport;
+using Thrift.Transport.Server;
+
+namespace ThriftTest
+{
+ internal enum ProtocolChoice
+ {
+ Binary,
+ Compact,
+ Json
+ }
+
+ internal enum TransportChoice
+ {
+ Socket,
+ TlsSocket,
+ NamedPipe
+ }
+
+ internal enum BufferChoice
+ {
+ None,
+ Buffered,
+ Framed
+ }
+
+ internal class ServerParam
+ {
+ internal BufferChoice buffering = BufferChoice.None;
+ internal ProtocolChoice protocol = ProtocolChoice.Binary;
+ internal TransportChoice transport = TransportChoice.Socket;
+ internal int port = 9090;
+ internal string pipe = null;
+
+ internal void Parse(List<string> args)
+ {
+ for (var i = 0; i < args.Count; i++)
+ {
+ if (args[i].StartsWith("--pipe="))
+ {
+ pipe = args[i].Substring(args[i].IndexOf("=") + 1);
+ transport = TransportChoice.NamedPipe;
+ }
+ else if (args[i].StartsWith("--port="))
+ {
+ port = int.Parse(args[i].Substring(args[i].IndexOf("=") + 1));
+ if(transport != TransportChoice.TlsSocket)
+ transport = TransportChoice.Socket;
+ }
+ else if (args[i] == "-b" || args[i] == "--buffered" || args[i] == "--transport=buffered")
+ {
+ buffering = BufferChoice.Buffered;
+ }
+ else if (args[i] == "-f" || args[i] == "--framed" || args[i] == "--transport=framed")
+ {
+ buffering = BufferChoice.Framed;
+ }
+ else if (args[i] == "--binary" || args[i] == "--protocol=binary")
+ {
+ protocol = ProtocolChoice.Binary;
+ }
+ else if (args[i] == "--compact" || args[i] == "--protocol=compact")
+ {
+ protocol = ProtocolChoice.Compact;
+ }
+ else if (args[i] == "--json" || args[i] == "--protocol=json")
+ {
+ protocol = ProtocolChoice.Json;
+ }
+ else if (args[i] == "--threaded" || args[i] == "--server-type=threaded")
+ {
+ throw new NotImplementedException(args[i]);
+ }
+ else if (args[i] == "--threadpool" || args[i] == "--server-type=threadpool")
+ {
+ throw new NotImplementedException(args[i]);
+ }
+ else if (args[i] == "--prototype" || args[i] == "--processor=prototype")
+ {
+ throw new NotImplementedException(args[i]);
+ }
+ else if (args[i] == "--ssl")
+ {
+ transport = TransportChoice.TlsSocket;
+ }
+ else if (args[i] == "--help")
+ {
+ PrintOptionsHelp();
+ return;
+ }
+ else
+ {
+ Console.WriteLine("Invalid argument: {0}", args[i]);
+ PrintOptionsHelp();
+ return;
+ }
+ }
+
+ }
+
+ internal static void PrintOptionsHelp()
+ {
+ Console.WriteLine("Server options:");
+ Console.WriteLine(" --pipe=<pipe name>");
+ Console.WriteLine(" --port=<port number>");
+ Console.WriteLine(" --transport=<transport name> one of buffered,framed (defaults to none)");
+ Console.WriteLine(" --protocol=<protocol name> one of compact,json (defaults to binary)");
+ Console.WriteLine(" --server-type=<type> one of threaded,threadpool (defaults to simple)");
+ Console.WriteLine(" --processor=<prototype>");
+ Console.WriteLine(" --ssl");
+ Console.WriteLine();
+ }
+ }
+
+ public class TestServer
+ {
+ public static int _clientID = -1;
+ public delegate void TestLogDelegate(string msg, params object[] values);
+
+ public class MyServerEventHandler : TServerEventHandler
+ {
+ public int callCount = 0;
+
+ public Task PreServeAsync(CancellationToken cancellationToken)
+ {
+ callCount++;
+ return Task.CompletedTask;
+ }
+
+ public Task<object> CreateContextAsync(TProtocol input, TProtocol output, CancellationToken cancellationToken)
+ {
+ callCount++;
+ return Task.FromResult<object>(null);
+ }
+
+ public Task DeleteContextAsync(object serverContext, TProtocol input, TProtocol output, CancellationToken cancellationToken)
+ {
+ callCount++;
+ return Task.CompletedTask;
+ }
+
+ public Task ProcessContextAsync(object serverContext, TTransport transport, CancellationToken cancellationToken)
+ {
+ callCount++;
+ return Task.CompletedTask;
+ }
+ }
+
+ public class TestHandlerAsync : ThriftTest.IAsync
+ {
+ public TServer server { get; set; }
+ private int handlerID;
+ private StringBuilder sb = new StringBuilder();
+ private TestLogDelegate logger;
+
+ public TestHandlerAsync()
+ {
+ handlerID = Interlocked.Increment(ref _clientID);
+ logger += testConsoleLogger;
+ logger.Invoke("New TestHandler instance created");
+ }
+
+ public void testConsoleLogger(string msg, params object[] values)
+ {
+ sb.Clear();
+ sb.AppendFormat("handler{0:D3}:", handlerID);
+ sb.AppendFormat(msg, values);
+ sb.AppendLine();
+ Console.Write(sb.ToString());
+ }
+
+ public Task testVoidAsync(CancellationToken cancellationToken)
+ {
+ logger.Invoke("testVoid()");
+ return Task.CompletedTask;
+ }
+
+ public Task<string> testStringAsync(string thing, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testString({0})", thing);
+ return Task.FromResult(thing);
+ }
+
+ public Task<bool> testBoolAsync(bool thing, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testBool({0})", thing);
+ return Task.FromResult(thing);
+ }
+
+ public Task<sbyte> testByteAsync(sbyte thing, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testByte({0})", thing);
+ return Task.FromResult(thing);
+ }
+
+ public Task<int> testI32Async(int thing, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testI32({0})", thing);
+ return Task.FromResult(thing);
+ }
+
+ public Task<long> testI64Async(long thing, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testI64({0})", thing);
+ return Task.FromResult(thing);
+ }
+
+ public Task<double> testDoubleAsync(double thing, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testDouble({0})", thing);
+ return Task.FromResult(thing);
+ }
+
+ public Task<byte[]> testBinaryAsync(byte[] thing, CancellationToken cancellationToken)
+ {
+ var hex = BitConverter.ToString(thing).Replace("-", string.Empty);
+ logger.Invoke("testBinary({0:X})", hex);
+ return Task.FromResult(thing);
+ }
+
+ public Task<Xtruct> testStructAsync(Xtruct thing, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testStruct({{\"{0}\", {1}, {2}, {3}}})", thing.String_thing, thing.Byte_thing, thing.I32_thing, thing.I64_thing);
+ return Task.FromResult(thing);
+ }
+
+ public Task<Xtruct2> testNestAsync(Xtruct2 nest, CancellationToken cancellationToken)
+ {
+ var thing = nest.Struct_thing;
+ logger.Invoke("testNest({{{0}, {{\"{1}\", {2}, {3}, {4}, {5}}}}})",
+ nest.Byte_thing,
+ thing.String_thing,
+ thing.Byte_thing,
+ thing.I32_thing,
+ thing.I64_thing,
+ nest.I32_thing);
+ return Task.FromResult(nest);
+ }
+
+ public Task<Dictionary<int, int>> testMapAsync(Dictionary<int, int> thing, CancellationToken cancellationToken)
+ {
+ sb.Clear();
+ sb.Append("testMap({{");
+ var first = true;
+ foreach (var key in thing.Keys)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ sb.Append(", ");
+ }
+ sb.AppendFormat("{0} => {1}", key, thing[key]);
+ }
+ sb.Append("}})");
+ logger.Invoke(sb.ToString());
+ return Task.FromResult(thing);
+ }
+
+ public Task<Dictionary<string, string>> testStringMapAsync(Dictionary<string, string> thing, CancellationToken cancellationToken)
+ {
+ sb.Clear();
+ sb.Append("testStringMap({{");
+ var first = true;
+ foreach (var key in thing.Keys)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ sb.Append(", ");
+ }
+ sb.AppendFormat("{0} => {1}", key, thing[key]);
+ }
+ sb.Append("}})");
+ logger.Invoke(sb.ToString());
+ return Task.FromResult(thing);
+ }
+
+ public Task<THashSet<int>> testSetAsync(THashSet<int> thing, CancellationToken cancellationToken)
+ {
+ sb.Clear();
+ sb.Append("testSet({{");
+ var first = true;
+ foreach (int elem in thing)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ sb.Append(", ");
+ }
+ sb.AppendFormat("{0}", elem);
+ }
+ sb.Append("}})");
+ logger.Invoke(sb.ToString());
+ return Task.FromResult(thing);
+ }
+
+ public Task<List<int>> testListAsync(List<int> thing, CancellationToken cancellationToken)
+ {
+ sb.Clear();
+ sb.Append("testList({{");
+ var first = true;
+ foreach (var elem in thing)
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ sb.Append(", ");
+ }
+ sb.AppendFormat("{0}", elem);
+ }
+ sb.Append("}})");
+ logger.Invoke(sb.ToString());
+ return Task.FromResult(thing);
+ }
+
+ public Task<Numberz> testEnumAsync(Numberz thing, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testEnum({0})", thing);
+ return Task.FromResult(thing);
+ }
+
+ public Task<long> testTypedefAsync(long thing, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testTypedef({0})", thing);
+ return Task.FromResult(thing);
+ }
+
+ public Task<Dictionary<int, Dictionary<int, int>>> testMapMapAsync(int hello, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testMapMap({0})", hello);
+ var mapmap = new Dictionary<int, Dictionary<int, int>>();
+
+ var pos = new Dictionary<int, int>();
+ var neg = new Dictionary<int, int>();
+ for (var i = 1; i < 5; i++)
+ {
+ pos[i] = i;
+ neg[-i] = -i;
+ }
+
+ mapmap[4] = pos;
+ mapmap[-4] = neg;
+
+ return Task.FromResult(mapmap);
+ }
+
+ public Task<Dictionary<long, Dictionary<Numberz, Insanity>>> testInsanityAsync(Insanity argument, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testInsanity()");
+
+ /** from ThriftTest.thrift:
+ * So you think you've got this all worked, out eh?
+ *
+ * Creates a the returned map with these values and prints it out:
+ * { 1 => { 2 => argument,
+ * 3 => argument,
+ * },
+ * 2 => { 6 => <empty Insanity struct>, },
+ * }
+ * @return map<UserId, map<Numberz,Insanity>> - a map with the above values
+ */
+
+ var first_map = new Dictionary<Numberz, Insanity>();
+ var second_map = new Dictionary<Numberz, Insanity>(); ;
+
+ first_map[Numberz.TWO] = argument;
+ first_map[Numberz.THREE] = argument;
+
+ second_map[Numberz.SIX] = new Insanity();
+
+ var insane = new Dictionary<long, Dictionary<Numberz, Insanity>>
+ {
+ [1] = first_map,
+ [2] = second_map
+ };
+
+ return Task.FromResult(insane);
+ }
+
+ public Task<Xtruct> testMultiAsync(sbyte arg0, int arg1, long arg2, Dictionary<short, string> arg3, Numberz arg4, long arg5,
+ CancellationToken cancellationToken)
+ {
+ logger.Invoke("testMulti()");
+
+ var hello = new Xtruct(); ;
+ hello.String_thing = "Hello2";
+ hello.Byte_thing = arg0;
+ hello.I32_thing = arg1;
+ hello.I64_thing = arg2;
+ return Task.FromResult(hello);
+ }
+
+ public Task testExceptionAsync(string arg, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testException({0})", arg);
+ if (arg == "Xception")
+ {
+ var x = new Xception
+ {
+ ErrorCode = 1001,
+ Message = arg
+ };
+ throw x;
+ }
+ if (arg == "TException")
+ {
+ throw new TException();
+ }
+ return Task.CompletedTask;
+ }
+
+ public Task<Xtruct> testMultiExceptionAsync(string arg0, string arg1, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testMultiException({0}, {1})", arg0, arg1);
+ if (arg0 == "Xception")
+ {
+ var x = new Xception
+ {
+ ErrorCode = 1001,
+ Message = "This is an Xception"
+ };
+ throw x;
+ }
+
+ if (arg0 == "Xception2")
+ {
+ var x = new Xception2
+ {
+ ErrorCode = 2002,
+ Struct_thing = new Xtruct { String_thing = "This is an Xception2" }
+ };
+ throw x;
+ }
+
+ var result = new Xtruct { String_thing = arg1 };
+ return Task.FromResult(result);
+ }
+
+ public Task testOnewayAsync(int secondsToSleep, CancellationToken cancellationToken)
+ {
+ logger.Invoke("testOneway({0}), sleeping...", secondsToSleep);
+ Task.Delay(secondsToSleep * 1000, cancellationToken).GetAwaiter().GetResult();
+ logger.Invoke("testOneway finished");
+
+ return Task.CompletedTask;
+ }
+ }
+
+
+ private static X509Certificate2 GetServerCert()
+ {
+ var serverCertName = "server.p12";
+ var possiblePaths = new List<string>
+ {
+ "../../../keys/",
+ "../../keys/",
+ "../keys/",
+ "keys/",
+ };
+
+ string existingPath = null;
+ foreach (var possiblePath in possiblePaths)
+ {
+ var path = Path.GetFullPath(possiblePath + serverCertName);
+ if (File.Exists(path))
+ {
+ existingPath = path;
+ break;
+ }
+ }
+
+ if (string.IsNullOrEmpty(existingPath))
+ {
+ throw new FileNotFoundException($"Cannot find file: {serverCertName}");
+ }
+
+ var cert = new X509Certificate2(existingPath, "thrift");
+
+ return cert;
+ }
+
+ public static int Execute(List<string> args)
+ {
+ var loggerFactory = new LoggerFactory();//.AddConsole().AddDebug();
+ var logger = new LoggerFactory().CreateLogger("Test");
+
+ try
+ {
+ var param = new ServerParam();
+
+ try
+ {
+ param.Parse(args);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("*** FAILED ***");
+ Console.WriteLine("Error while parsing arguments");
+ Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
+ return 1;
+ }
+
+
+ // Endpoint transport (mandatory)
+ TServerTransport trans;
+ switch (param.transport)
+ {
+ case TransportChoice.NamedPipe:
+ Debug.Assert(param.pipe != null);
+ trans = new TNamedPipeServerTransport(param.pipe);
+ break;
+
+
+ case TransportChoice.TlsSocket:
+ var cert = GetServerCert();
+ if (cert == null || !cert.HasPrivateKey)
+ {
+ throw new InvalidOperationException("Certificate doesn't contain private key");
+ }
+
+ trans = new TTlsServerSocketTransport( param.port, cert,
+ (sender, certificate, chain, errors) => true,
+ null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12);
+ break;
+
+ case TransportChoice.Socket:
+ default:
+ trans = new TServerSocketTransport(param.port, 0);
+ break;
+ }
+
+ // Layered transport (mandatory)
+ TTransportFactory transFactory = null;
+ switch (param.buffering)
+ {
+ case BufferChoice.Framed:
+ transFactory = new TFramedTransport.Factory();
+ break;
+ case BufferChoice.Buffered:
+ transFactory = new TBufferedTransport.Factory();
+ break;
+ default:
+ Debug.Assert(param.buffering == BufferChoice.None, "unhandled case");
+ transFactory = null; // no layered transprt
+ break;
+ }
+
+ // Protocol (mandatory)
+ TProtocolFactory proto;
+ switch (param.protocol)
+ {
+ case ProtocolChoice.Compact:
+ proto = new TCompactProtocol.Factory();
+ break;
+ case ProtocolChoice.Json:
+ proto = new TJsonProtocol.Factory();
+ break;
+ case ProtocolChoice.Binary:
+ default:
+ proto = new TBinaryProtocol.Factory();
+ break;
+ }
+
+ // Processor
+ var testHandler = new TestHandlerAsync();
+ var testProcessor = new ThriftTest.AsyncProcessor(testHandler);
+ var processorFactory = new TSingletonProcessorFactory(testProcessor);
+
+ TServer serverEngine = new TSimpleAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, logger);
+
+ //Server event handler
+ var serverEvents = new MyServerEventHandler();
+ serverEngine.SetEventHandler(serverEvents);
+
+ // Run it
+ var where = (! string.IsNullOrEmpty(param.pipe)) ? "on pipe " + param.pipe : "on port " + param.port;
+ Console.WriteLine("Starting the AsyncBaseServer " + where +
+ " with processor TPrototypeProcessorFactory prototype factory " +
+ (param.buffering == BufferChoice.Buffered ? " with buffered transport" : "") +
+ (param.buffering == BufferChoice.Framed ? " with framed transport" : "") +
+ (param.transport == TransportChoice.TlsSocket ? " with encryption" : "") +
+ (param.protocol == ProtocolChoice.Compact ? " with compact protocol" : "") +
+ (param.protocol == ProtocolChoice.Json ? " with json protocol" : "") +
+ "...");
+ serverEngine.ServeAsync(CancellationToken.None).GetAwaiter().GetResult();
+ Console.ReadLine();
+ }
+ catch (Exception x)
+ {
+ Console.Error.Write(x);
+ return 1;
+ }
+ Console.WriteLine("done.");
+ return 0;
+ }
+ }
+
+}
diff --git a/test/netstd/ThriftTest.sln b/test/netstd/ThriftTest.sln
new file mode 100644
index 0000000..6bd0855
--- /dev/null
+++ b/test/netstd/ThriftTest.sln
@@ -0,0 +1,64 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26730.12
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", "..\..\lib\netstd\Thrift\Thrift.csproj", "{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "Client\Client.csproj", "{21039F25-6ED7-4E80-A545-EBC93472EBD1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csproj", "{0C6E8685-F191-4479-9842-882A38961127}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.Build.0 = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.Build.0 = Release|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|x64.Build.0 = Debug|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Debug|x86.Build.0 = Debug|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|x64.ActiveCfg = Release|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|x64.Build.0 = Release|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|x86.ActiveCfg = Release|Any CPU
+ {21039F25-6ED7-4E80-A545-EBC93472EBD1}.Release|x86.Build.0 = Release|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Debug|x64.Build.0 = Debug|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Debug|x86.Build.0 = Debug|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Release|x64.ActiveCfg = Release|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Release|x64.Build.0 = Release|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Release|x86.ActiveCfg = Release|Any CPU
+ {0C6E8685-F191-4479-9842-882A38961127}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {52CE9A12-F6CB-4F0C-BB42-0105612F5FF4}
+ EndGlobalSection
+EndGlobal
diff --git a/test/netstd/build.cmd b/test/netstd/build.cmd
new file mode 100644
index 0000000..9b84ef2
--- /dev/null
+++ b/test/netstd/build.cmd
@@ -0,0 +1,25 @@
+@echo off
+rem /*
+rem * Licensed to the Apache Software Foundation (ASF) under one
+rem * or more contributor license agreements. See the NOTICE file
+rem * distributed with this work for additional information
+rem * regarding copyright ownership. The ASF licenses this file
+rem * to you under the Apache License, Version 2.0 (the
+rem * "License"); you may not use this file except in compliance
+rem * with the License. You may obtain a copy of the License at
+rem *
+rem * http://www.apache.org/licenses/LICENSE-2.0
+rem *
+rem * Unless required by applicable law or agreed to in writing,
+rem * software distributed under the License is distributed on an
+rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem * KIND, either express or implied. See the License for the
+rem * specific language governing permissions and limitations
+rem * under the License.
+rem */
+setlocal
+
+dotnet --info
+dotnet build
+
+:eof
diff --git a/lib/cpp/thrift-qt.pc.in b/test/netstd/build.sh
old mode 100755
new mode 100644
similarity index 77%
copy from lib/cpp/thrift-qt.pc.in
copy to test/netstd/build.sh
index 5e60d84..c97e310
--- a/lib/cpp/thrift-qt.pc.in
+++ b/test/netstd/build.sh
@@ -1,3 +1,5 @@
+#!/usr/bin/env bash
+
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -17,14 +19,8 @@
# under the License.
#
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
+#exit if any command fails
+set -e
-Name: Thrift
-Description: Thrift Qt API
-Version: @VERSION@
-Requires: thrift = @VERSION@
-Libs: -L${libdir} -lthriftqt
-Cflags: -I${includedir}
+dotnet --info
+dotnet build
diff --git a/test/perl/Makefile.am b/test/perl/Makefile.am
index 165b9a7..1dbaf28 100644
--- a/test/perl/Makefile.am
+++ b/test/perl/Makefile.am
@@ -25,5 +25,7 @@
check: stubs
clean-local:
- $(RM) -r gen-perl
+ $(RM) -r gen-perl/
+dist-hook:
+ $(RM) -r $(distdir)/gen-perl/
diff --git a/test/php/Makefile.am b/test/php/Makefile.am
index 72f7fc5..52765ee 100755
--- a/test/php/Makefile.am
+++ b/test/php/Makefile.am
@@ -26,6 +26,7 @@
php_ext_dir:
mkdir -p php_ext_dir
ln -s ../../../lib/php/src/ext/thrift_protocol/modules/thrift_protocol.so php_ext_dir/
+ ln -s "$$(php-config --extension-dir)/json.so" php_ext_dir/
ln -s "$$(php-config --extension-dir)/sockets.so" php_ext_dir/
precross: stubs php_ext_dir
@@ -33,7 +34,12 @@
check: stubs php_ext_dir
clean-local:
- $(RM) -r gen-php gen-phpi gen-php-classmap php_ext_dir
+ $(RM) -r gen-*/
+ $(RM) -r php_ext_dir
+
+dist-hook:
+ $(RM) -r $(distdir)/gen-*/
+ $(RM) -r $(distdir)/php_ext_dir/
client: stubs php_ext_dir
php TestClient.php
diff --git a/test/php/test_php.ini b/test/php/test_php.ini
index 3f9bb21..aeb67cb 100644
--- a/test/php/test_php.ini
+++ b/test/php/test_php.ini
@@ -1,2 +1,3 @@
extension=thrift_protocol.so
+extension=json.so
extension=sockets.so
diff --git a/test/py.tornado/Makefile.am b/test/py.tornado/Makefile.am
index a8e680a..e962f0c 100644
--- a/test/py.tornado/Makefile.am
+++ b/test/py.tornado/Makefile.am
@@ -27,4 +27,12 @@
./test_suite.py
clean-local:
- $(RM) -r gen-py.tornado
+ $(RM) -r build
+ find . -type f \( -iname "*.pyc" \) | xargs rm -f
+ find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
+ $(RM) -r gen-py*/
+
+dist-hook:
+ find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f
+ find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
+ $(RM) -r $(distdir)/gen-py*/
diff --git a/test/py.twisted/Makefile.am b/test/py.twisted/Makefile.am
index d11908c..dee8e2f 100644
--- a/test/py.twisted/Makefile.am
+++ b/test/py.twisted/Makefile.am
@@ -27,4 +27,12 @@
$(TRIAL) ./test_suite.py
clean-local:
- $(RM) -r gen-py.twisted
+ $(RM) -r build
+ find . -type f \( -iname "*.pyc" \) | xargs rm -f
+ find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
+ $(RM) -r gen-py*/
+
+dist-hook:
+ find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f
+ find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
+ $(RM) -r $(distdir)/gen-py*/
diff --git a/test/py/Makefile.am b/test/py/Makefile.am
index 8296200..9433e59 100644
--- a/test/py/Makefile.am
+++ b/test/py/Makefile.am
@@ -94,4 +94,12 @@
$(THRIFT) --gen py:dynamic,slots -out gen-py-dynamicslots $<
clean-local:
- $(RM) -r gen-py gen-py-slots gen-py-default gen-py-oldstyle gen-py-no_utf8strings gen-py-dynamic gen-py-dynamicslots
+ $(RM) -r build
+ find . -type f \( -iname "*.pyc" \) | xargs rm -f
+ find . -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
+ $(RM) -r gen-py*/
+
+dist-hook:
+ find $(distdir) -type f \( -iname "*.pyc" \) | xargs rm -f
+ find $(distdir) -type d \( -iname "__pycache__" -or -iname "_trial_temp" \) | xargs rm -rf
+ $(RM) -r $(distdir)/gen-py*/
diff --git a/test/py/TestClient.py b/test/py/TestClient.py
index ddcce8d..e7a9a1a 100755
--- a/test/py/TestClient.py
+++ b/test/py/TestClient.py
@@ -23,9 +23,11 @@
import sys
import time
import unittest
-from optparse import OptionParser
+from optparse import OptionParser
from util import local_libpath
+sys.path.insert(0, local_libpath())
+from thrift.protocol import TProtocol, TProtocolDecorator
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
@@ -268,6 +270,47 @@
self.assertEqual(self.client.testString('Python'), 'Python')
+# LAST_SEQID is a global because we have one transport and multiple protocols
+# running on it (when multiplexed)
+LAST_SEQID = None
+
+
+class TPedanticSequenceIdProtocolWrapper(TProtocolDecorator.TProtocolDecorator):
+ """
+ Wraps any protocol with sequence ID checking: looks for outbound
+ uniqueness as well as request/response alignment.
+ """
+ def __init__(self, protocol):
+ # TProtocolDecorator.__new__ does all the heavy lifting
+ pass
+
+ def writeMessageBegin(self, name, type, seqid):
+ global LAST_SEQID
+ if LAST_SEQID and LAST_SEQID == seqid:
+ raise TProtocol.TProtocolException(
+ TProtocol.TProtocolException.INVALID_DATA,
+ "Python client reused sequence ID {0}".format(seqid))
+ LAST_SEQID = seqid
+ super(TPedanticSequenceIdProtocolWrapper, self).writeMessageBegin(
+ name, type, seqid)
+
+ def readMessageBegin(self):
+ global LAST_SEQID
+ (name, type, seqid) =\
+ super(TPedanticSequenceIdProtocolWrapper, self).readMessageBegin()
+ if LAST_SEQID != seqid:
+ raise TProtocol.TProtocolException(
+ TProtocol.TProtocolException.INVALID_DATA,
+ "We sent seqid {0} and server returned seqid {1}".format(
+ self.last, seqid))
+ return (name, type, seqid)
+
+
+def make_pedantic(proto):
+ """ Wrap a protocol in the pedantic sequence ID wrapper. """
+ return TPedanticSequenceIdProtocolWrapper(proto)
+
+
class MultiplexedOptionalTest(AbstractTest):
def get_protocol2(self, transport):
return None
@@ -275,83 +318,93 @@
class BinaryTest(MultiplexedOptionalTest):
def get_protocol(self, transport):
- return TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport)
+ return make_pedantic(TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport))
class MultiplexedBinaryTest(MultiplexedOptionalTest):
def get_protocol(self, transport):
- wrapped_proto = TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport)
+ wrapped_proto = make_pedantic(TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport))
return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")
def get_protocol2(self, transport):
- wrapped_proto = TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport)
+ wrapped_proto = make_pedantic(TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport))
return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")
class AcceleratedBinaryTest(MultiplexedOptionalTest):
def get_protocol(self, transport):
- return TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(transport)
+ return make_pedantic(TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(transport))
class MultiplexedAcceleratedBinaryTest(MultiplexedOptionalTest):
def get_protocol(self, transport):
- wrapped_proto = TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(transport)
+ wrapped_proto = make_pedantic(TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(transport))
return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")
def get_protocol2(self, transport):
- wrapped_proto = TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(transport)
+ wrapped_proto = make_pedantic(TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(transport))
return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")
class CompactTest(MultiplexedOptionalTest):
def get_protocol(self, transport):
- return TCompactProtocol.TCompactProtocolFactory().getProtocol(transport)
+ return make_pedantic(TCompactProtocol.TCompactProtocolFactory().getProtocol(transport))
class MultiplexedCompactTest(MultiplexedOptionalTest):
def get_protocol(self, transport):
- wrapped_proto = TCompactProtocol.TCompactProtocolFactory().getProtocol(transport)
+ wrapped_proto = make_pedantic(TCompactProtocol.TCompactProtocolFactory().getProtocol(transport))
return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")
def get_protocol2(self, transport):
- wrapped_proto = TCompactProtocol.TCompactProtocolFactory().getProtocol(transport)
+ wrapped_proto = make_pedantic(TCompactProtocol.TCompactProtocolFactory().getProtocol(transport))
return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")
class AcceleratedCompactTest(MultiplexedOptionalTest):
def get_protocol(self, transport):
- return TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(transport)
+ return make_pedantic(TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(transport))
class MultiplexedAcceleratedCompactTest(MultiplexedOptionalTest):
def get_protocol(self, transport):
- wrapped_proto = TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(transport)
+ wrapped_proto = make_pedantic(TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(transport))
return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")
def get_protocol2(self, transport):
- wrapped_proto = TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(transport)
+ wrapped_proto = make_pedantic(TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(transport))
return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")
class JSONTest(MultiplexedOptionalTest):
def get_protocol(self, transport):
- return TJSONProtocol.TJSONProtocolFactory().getProtocol(transport)
+ return make_pedantic(TJSONProtocol.TJSONProtocolFactory().getProtocol(transport))
class MultiplexedJSONTest(MultiplexedOptionalTest):
def get_protocol(self, transport):
- wrapped_proto = TJSONProtocol.TJSONProtocolFactory().getProtocol(transport)
+ wrapped_proto = make_pedantic(TJSONProtocol.TJSONProtocolFactory().getProtocol(transport))
return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")
def get_protocol2(self, transport):
- wrapped_proto = TJSONProtocol.TJSONProtocolFactory().getProtocol(transport)
+ wrapped_proto = make_pedantic(TJSONProtocol.TJSONProtocolFactory().getProtocol(transport))
return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")
class HeaderTest(MultiplexedOptionalTest):
def get_protocol(self, transport):
factory = THeaderProtocol.THeaderProtocolFactory()
- return factory.getProtocol(transport)
+ return make_pedantic(factory.getProtocol(transport))
+
+
+class MultiplexedHeaderTest(MultiplexedOptionalTest):
+ def get_protocol(self, transport):
+ wrapped_proto = make_pedantic(THeaderProtocol.THeaderProtocolFactory().getProtocol(transport))
+ return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "ThriftTest")
+
+ def get_protocol2(self, transport):
+ wrapped_proto = make_pedantic(THeaderProtocol.THeaderProtocolFactory().getProtocol(transport))
+ return TMultiplexedProtocol.TMultiplexedProtocol(wrapped_proto, "SecondService")
def suite():
@@ -377,6 +430,8 @@
suite.addTest(loader.loadTestsFromTestCase(MultiplexedAcceleratedCompactTest))
elif options.proto == 'multic':
suite.addTest(loader.loadTestsFromTestCase(MultiplexedCompactTest))
+ elif options.proto == 'multih':
+ suite.addTest(loader.loadTestsFromTestCase(MultiplexedHeaderTest))
elif options.proto == 'multij':
suite.addTest(loader.loadTestsFromTestCase(MultiplexedJSONTest))
else:
@@ -416,7 +471,7 @@
dest="verbose", const=0,
help="minimal output")
parser.add_option('--protocol', dest="proto", type="string",
- help="protocol to use, one of: accel, accelc, binary, compact, header, json, multi, multia, multiac, multic, multij")
+ help="protocol to use, one of: accel, accelc, binary, compact, header, json, multi, multia, multiac, multic, multih, multij")
parser.add_option('--transport', dest="trans", type="string",
help="transport to use, one of: buffered, framed, http")
parser.set_defaults(framed=False, http_path=None, verbose=1, host='localhost', port=9090, proto='binary')
@@ -424,7 +479,6 @@
if options.genpydir:
sys.path.insert(0, os.path.join(SCRIPT_DIR, options.genpydir))
- sys.path.insert(0, local_libpath())
if options.http_path:
options.trans = 'http'
diff --git a/test/py/TestServer.py b/test/py/TestServer.py
index aba0d42..d0a13e5 100755
--- a/test/py/TestServer.py
+++ b/test/py/TestServer.py
@@ -27,6 +27,8 @@
from optparse import OptionParser
from util import local_libpath
+sys.path.insert(0, local_libpath())
+from thrift.protocol import TProtocol, TProtocolDecorator
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
@@ -178,21 +180,79 @@
byte_thing=arg0, i32_thing=arg1, i64_thing=arg2)
+class SecondHandler(object):
+ def secondtestString(self, argument):
+ return "testString(\"" + argument + "\")"
+
+
+# LAST_SEQID is a global because we have one transport and multiple protocols
+# running on it (when multiplexed)
+LAST_SEQID = None
+
+
+class TPedanticSequenceIdProtocolWrapper(TProtocolDecorator.TProtocolDecorator):
+ """
+ Wraps any protocol with sequence ID checking: looks for outbound
+ uniqueness as well as request/response alignment.
+ """
+ def __init__(self, protocol):
+ # TProtocolDecorator.__new__ does all the heavy lifting
+ pass
+
+ def readMessageBegin(self):
+ global LAST_SEQID
+ (name, type, seqid) =\
+ super(TPedanticSequenceIdProtocolWrapper, self).readMessageBegin()
+ if LAST_SEQID is not None and LAST_SEQID == seqid:
+ raise TProtocol.TProtocolException(
+ TProtocol.TProtocolException.INVALID_DATA,
+ "We received the same seqid {0} twice in a row".format(seqid))
+ LAST_SEQID = seqid
+ return (name, type, seqid)
+
+
+def make_pedantic(proto):
+ """ Wrap a protocol in the pedantic sequence ID wrapper. """
+ # NOTE: this is disabled for now as many clients send seqid
+ # of zero and that is okay, need a way to identify
+ # clients that MUST send seqid unique to function right
+ # or just force all implementations to send unique seqids (preferred)
+ return proto # TPedanticSequenceIdProtocolWrapper(proto)
+
+
+class TPedanticSequenceIdProtocolFactory(TProtocol.TProtocolFactory):
+ def __init__(self, encapsulated):
+ super(TPedanticSequenceIdProtocolFactory, self).__init__()
+ self.encapsulated = encapsulated
+
+ def getProtocol(self, trans):
+ return make_pedantic(self.encapsulated.getProtocol(trans))
+
+
def main(options):
+ # common header allowed client types
+ allowed_client_types = [
+ THeaderTransport.THeaderClientType.HEADERS,
+ THeaderTransport.THeaderClientType.FRAMED_BINARY,
+ THeaderTransport.THeaderClientType.UNFRAMED_BINARY,
+ THeaderTransport.THeaderClientType.FRAMED_COMPACT,
+ THeaderTransport.THeaderClientType.UNFRAMED_COMPACT,
+ ]
+
# set up the protocol factory form the --protocol option
prot_factories = {
'accel': TBinaryProtocol.TBinaryProtocolAcceleratedFactory(),
+ 'multia': TBinaryProtocol.TBinaryProtocolAcceleratedFactory(),
'accelc': TCompactProtocol.TCompactProtocolAcceleratedFactory(),
- 'binary': TBinaryProtocol.TBinaryProtocolFactory(),
+ 'multiac': TCompactProtocol.TCompactProtocolAcceleratedFactory(),
+ 'binary': TPedanticSequenceIdProtocolFactory(TBinaryProtocol.TBinaryProtocolFactory()),
+ 'multi': TPedanticSequenceIdProtocolFactory(TBinaryProtocol.TBinaryProtocolFactory()),
'compact': TCompactProtocol.TCompactProtocolFactory(),
- 'header': THeaderProtocol.THeaderProtocolFactory(allowed_client_types=[
- THeaderTransport.THeaderClientType.HEADERS,
- THeaderTransport.THeaderClientType.FRAMED_BINARY,
- THeaderTransport.THeaderClientType.UNFRAMED_BINARY,
- THeaderTransport.THeaderClientType.FRAMED_COMPACT,
- THeaderTransport.THeaderClientType.UNFRAMED_COMPACT,
- ]),
+ 'multic': TCompactProtocol.TCompactProtocolFactory(),
+ 'header': THeaderProtocol.THeaderProtocolFactory(allowed_client_types),
+ 'multih': THeaderProtocol.THeaderProtocolFactory(allowed_client_types),
'json': TJSONProtocol.TJSONProtocolFactory(),
+ 'multij': TJSONProtocol.TJSONProtocolFactory(),
}
pfactory = prot_factories.get(options.proto, None)
if pfactory is None:
@@ -215,6 +275,16 @@
handler = TestHandler()
processor = ThriftTest.Processor(handler)
+ if options.proto.startswith('multi'):
+ secondHandler = SecondHandler()
+ secondProcessor = SecondService.Processor(secondHandler)
+
+ multiplexedProcessor = TMultiplexedProcessor()
+ multiplexedProcessor.registerDefault(processor)
+ multiplexedProcessor.registerProcessor('ThriftTest', processor)
+ multiplexedProcessor.registerProcessor('SecondService', secondProcessor)
+ processor = multiplexedProcessor
+
global server
# Handle THttpServer as a special case
@@ -312,7 +382,7 @@
dest="verbose", const=0,
help="minimal output")
parser.add_option('--protocol', dest="proto", type="string",
- help="protocol to use, one of: accel, accelc, binary, compact, json")
+ help="protocol to use, one of: accel, accelc, binary, compact, json, multi, multia, multiac, multic, multih, multij")
parser.add_option('--transport', dest="trans", type="string",
help="transport to use, one of: buffered, framed, http")
parser.add_option('--container-limit', dest='container_limit', type='int', default=None)
@@ -324,11 +394,11 @@
logging.basicConfig(level=options.verbose)
sys.path.insert(0, os.path.join(SCRIPT_DIR, options.genpydir))
- sys.path.insert(0, local_libpath())
- from ThriftTest import ThriftTest
+ from ThriftTest import ThriftTest, SecondService
from ThriftTest.ttypes import Xtruct, Xception, Xception2, Insanity
from thrift.Thrift import TException
+ from thrift.TMultiplexedProcessor import TMultiplexedProcessor
from thrift.transport import THeaderTransport
from thrift.transport import TTransport
from thrift.transport import TSocket
diff --git a/test/rb/Makefile.am b/test/rb/Makefile.am
index cfdc149..3910934 100644
--- a/test/rb/Makefile.am
+++ b/test/rb/Makefile.am
@@ -30,3 +30,8 @@
$(BUNDLER) exec $(RUBY) -I. test_suite.rb
endif
+clean-local:
+ $(RM) -r gen-rb/
+
+dist-hook:
+ $(RM) -r $(distdir)/gen-rb/
diff --git a/test/rs/Makefile.am b/test/rs/Makefile.am
index 54905b4..4b061ea 100644
--- a/test/rs/Makefile.am
+++ b/test/rs/Makefile.am
@@ -34,7 +34,7 @@
EXTRA_DIST = \
Cargo.toml \
- src/lib.rs \
+ src/lib.rs \
src/bin/test_server.rs \
src/bin/test_client.rs
diff --git a/test/rs/src/bin/test_client.rs b/test/rs/src/bin/test_client.rs
index 29b5b88..8016ca6 100644
--- a/test/rs/src/bin/test_client.rs
+++ b/test/rs/src/bin/test_client.rs
@@ -65,7 +65,7 @@
(@arg host: --host +takes_value "Host on which the Thrift test server is located")
(@arg port: --port +takes_value "Port on which the Thrift test server is listening")
(@arg transport: --transport +takes_value "Thrift transport implementation to use (\"buffered\", \"framed\")")
- (@arg protocol: --protocol +takes_value "Thrift protocol implementation to use (\"binary\", \"compact\")")
+ (@arg protocol: --protocol +takes_value "Thrift protocol implementation to use (\"binary\", \"compact\", \"multi\", \"multic\")")
(@arg testloops: -n --testloops +takes_value "Number of times to run tests")
)
.get_matches();
diff --git a/test/tests.json b/test/tests.json
index 43d6ded..a4680d1 100644
--- a/test/tests.json
+++ b/test/tests.json
@@ -199,7 +199,8 @@
"protocols": [
"compact",
"binary",
- "json"
+ "json",
+ "header"
],
"workdir": "../lib/nodejs/test"
},
@@ -251,13 +252,6 @@
"--verbose",
"--host=localhost",
"--genpydir=gen-py"
- ],
- "protocols": [
- "multi",
- "multi:multia",
- "multic",
- "multic:multiac",
- "multij"
]
},
"transports": [
@@ -271,12 +265,20 @@
"ip-ssl"
],
"protocols": [
- "compact",
"binary",
- "json",
"binary:accel",
+ "compact",
"compact:accelc",
- "header"
+ "header",
+ "json",
+ "multi",
+ "multi:multia",
+ "multia",
+ "multiac",
+ "multic",
+ "multic:multiac",
+ "multih",
+ "multij"
],
"workdir": "py"
},
@@ -299,13 +301,6 @@
"TestClient.py",
"--host=localhost",
"--genpydir=gen-py"
- ],
- "protocols": [
- "multi",
- "multi:multia",
- "multic",
- "multic:multiac",
- "multij"
]
},
"transports": [
@@ -319,12 +314,20 @@
"ip-ssl"
],
"protocols": [
- "compact",
"binary",
- "json",
"binary:accel",
+ "compact",
"compact:accelc",
- "header"
+ "header",
+ "json",
+ "multi",
+ "multi:multia",
+ "multia",
+ "multiac",
+ "multic",
+ "multic:multiac",
+ "multih",
+ "multij"
],
"workdir": "py"
},
@@ -385,7 +388,7 @@
]
},
"client": {
- "timeout": 5,
+ "timeout": 10,
"command": [
"ruby",
"../integration/TestClient.rb",
@@ -543,8 +546,9 @@
],
"protocols": [
"binary",
+ "binary:accel",
"compact",
- "binary:accel"
+ "json"
],
"command": [
"php",
@@ -562,6 +566,7 @@
{
"name": "dart",
"client": {
+ "timeout": 30,
"transports": [
"buffered",
"framed",
@@ -577,7 +582,9 @@
],
"command": [
"dart",
- "test_client/bin/main.dart"
+ "--checked",
+ "test_client/bin/main.dart",
+ "--verbose"
]
},
"workdir": "dart"
diff --git a/test/threads/ThreadsClient.cpp b/test/threads/ThreadsClient.cpp
index 9306a3f..e8bd79e 100644
--- a/test/threads/ThreadsClient.cpp
+++ b/test/threads/ThreadsClient.cpp
@@ -27,7 +27,7 @@
#include <thrift/transport/TTransportUtils.h>
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/ThreadManager.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#if _WIN32
#include <thrift/windows/TWinsockSingleton.h>
#endif
diff --git a/test/threads/ThreadsServer.cpp b/test/threads/ThreadsServer.cpp
index a267c3b..3811b60 100644
--- a/test/threads/ThreadsServer.cpp
+++ b/test/threads/ThreadsServer.cpp
@@ -28,7 +28,7 @@
#include <thrift/transport/TTransportUtils.h>
#include <thrift/concurrency/Monitor.h>
#include <thrift/concurrency/ThreadManager.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#if _WIN32
#include <thrift/windows/TWinsockSingleton.h>
#endif
@@ -118,8 +118,8 @@
/*
shared_ptr<ThreadManager> threadManager =
ThreadManager::newSimpleThreadManager(10);
- shared_ptr<PlatformThreadFactory> threadFactory =
- shared_ptr<PlatformThreadFactory>(new PlatformThreadFactory());
+ shared_ptr<ThreadFactory> threadFactory =
+ shared_ptr<ThreadFactory>(new ThreadFactory());
threadManager->threadFactory(threadFactory);
threadManager->start();
diff --git a/tutorial/Makefile.am b/tutorial/Makefile.am
index 0499460..17a9257 100755
--- a/tutorial/Makefile.am
+++ b/tutorial/Makefile.am
@@ -58,8 +58,9 @@
SUBDIRS += haxe
endif
-if WITH_DOTNETCORE
+if WITH_DOTNET
SUBDIRS += netcore
+SUBDIRS += netstd
endif
if WITH_GO
diff --git a/tutorial/cpp/CMakeLists.txt b/tutorial/cpp/CMakeLists.txt
index 8634b41..c6d8fc3 100644
--- a/tutorial/cpp/CMakeLists.txt
+++ b/tutorial/cpp/CMakeLists.txt
@@ -17,7 +17,8 @@
# under the License.
#
-include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
+include(BoostMacros)
+REQUIRE_BOOST_HEADERS()
#Make sure gen-cpp files can be included
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/CppClient.cpp
index f10c725..5208411 100644
--- a/tutorial/cpp/CppClient.cpp
+++ b/tutorial/cpp/CppClient.cpp
@@ -22,7 +22,6 @@
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
-#include <thrift/stdcxx.h>
#include "../gen-cpp/Calculator.h"
@@ -35,9 +34,9 @@
using namespace shared;
int main() {
- stdcxx::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
- stdcxx::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
- stdcxx::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
+ std::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
+ std::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
+ std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
CalculatorClient client(protocol);
try {
diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp
index 80b100e..635afef 100644
--- a/tutorial/cpp/CppServer.cpp
+++ b/tutorial/cpp/CppServer.cpp
@@ -18,7 +18,7 @@
*/
#include <thrift/concurrency/ThreadManager.h>
-#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadFactory.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/server/TThreadPoolServer.h>
@@ -27,7 +27,6 @@
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/TToString.h>
-#include <thrift/stdcxx.h>
#include <iostream>
#include <stdexcept>
@@ -47,16 +46,16 @@
class CalculatorHandler : public CalculatorIf {
public:
- CalculatorHandler() {}
+ CalculatorHandler() = default;
- void ping() { cout << "ping()" << endl; }
+ void ping() override { cout << "ping()" << endl; }
- int32_t add(const int32_t n1, const int32_t n2) {
+ int32_t add(const int32_t n1, const int32_t n2) override {
cout << "add(" << n1 << ", " << n2 << ")" << endl;
return n1 + n2;
}
- int32_t calculate(const int32_t logid, const Work& work) {
+ int32_t calculate(const int32_t logid, const Work& work) override {
cout << "calculate(" << logid << ", " << work << ")" << endl;
int32_t val;
@@ -95,12 +94,12 @@
return val;
}
- void getStruct(SharedStruct& ret, const int32_t logid) {
+ void getStruct(SharedStruct& ret, const int32_t logid) override {
cout << "getStruct(" << logid << ")" << endl;
ret = log[logid];
}
- void zip() { cout << "zip()" << endl; }
+ void zip() override { cout << "zip()" << endl; }
protected:
map<int32_t, SharedStruct> log;
@@ -114,10 +113,10 @@
*/
class CalculatorCloneFactory : virtual public CalculatorIfFactory {
public:
- virtual ~CalculatorCloneFactory() {}
- virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo)
+ ~CalculatorCloneFactory() override = default;
+ CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) override
{
- stdcxx::shared_ptr<TSocket> sock = stdcxx::dynamic_pointer_cast<TSocket>(connInfo.transport);
+ std::shared_ptr<TSocket> sock = std::dynamic_pointer_cast<TSocket>(connInfo.transport);
cout << "Incoming connection\n";
cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n";
cout << "\tPeerHost: " << sock->getPeerHost() << "\n";
@@ -125,25 +124,25 @@
cout << "\tPeerPort: " << sock->getPeerPort() << "\n";
return new CalculatorHandler;
}
- virtual void releaseHandler( ::shared::SharedServiceIf* handler) {
+ void releaseHandler( ::shared::SharedServiceIf* handler) override {
delete handler;
}
};
int main() {
TThreadedServer server(
- stdcxx::make_shared<CalculatorProcessorFactory>(stdcxx::make_shared<CalculatorCloneFactory>()),
- stdcxx::make_shared<TServerSocket>(9090), //port
- stdcxx::make_shared<TBufferedTransportFactory>(),
- stdcxx::make_shared<TBinaryProtocolFactory>());
+ std::make_shared<CalculatorProcessorFactory>(std::make_shared<CalculatorCloneFactory>()),
+ std::make_shared<TServerSocket>(9090), //port
+ std::make_shared<TBufferedTransportFactory>(),
+ std::make_shared<TBinaryProtocolFactory>());
/*
// if you don't need per-connection state, do the following instead
TThreadedServer server(
- stdcxx::make_shared<CalculatorProcessor>(stdcxx::make_shared<CalculatorHandler>()),
- stdcxx::make_shared<TServerSocket>(9090), //port
- stdcxx::make_shared<TBufferedTransportFactory>(),
- stdcxx::make_shared<TBinaryProtocolFactory>());
+ std::make_shared<CalculatorProcessor>(std::make_shared<CalculatorHandler>()),
+ std::make_shared<TServerSocket>(9090), //port
+ std::make_shared<TBufferedTransportFactory>(),
+ std::make_shared<TBinaryProtocolFactory>());
*/
/**
@@ -151,25 +150,25 @@
// This server only allows one connection at a time, but spawns no threads
TSimpleServer server(
- stdcxx::make_shared<CalculatorProcessor>(stdcxx::make_shared<CalculatorHandler>()),
- stdcxx::make_shared<TServerSocket>(9090),
- stdcxx::make_shared<TBufferedTransportFactory>(),
- stdcxx::make_shared<TBinaryProtocolFactory>());
+ std::make_shared<CalculatorProcessor>(std::make_shared<CalculatorHandler>()),
+ std::make_shared<TServerSocket>(9090),
+ std::make_shared<TBufferedTransportFactory>(),
+ std::make_shared<TBinaryProtocolFactory>());
const int workerCount = 4;
- stdcxx::shared_ptr<ThreadManager> threadManager =
+ std::shared_ptr<ThreadManager> threadManager =
ThreadManager::newSimpleThreadManager(workerCount);
threadManager->threadFactory(
- stdcxx::make_shared<PlatformThreadFactory>());
+ std::make_shared<ThreadFactory>());
threadManager->start();
// This server allows "workerCount" connection at a time, and reuses threads
TThreadPoolServer server(
- stdcxx::make_shared<CalculatorProcessorFactory>(stdcxx::make_shared<CalculatorCloneFactory>()),
- stdcxx::make_shared<TServerSocket>(9090),
- stdcxx::make_shared<TBufferedTransportFactory>(),
- stdcxx::make_shared<TBinaryProtocolFactory>(),
+ std::make_shared<CalculatorProcessorFactory>(std::make_shared<CalculatorCloneFactory>()),
+ std::make_shared<TServerSocket>(9090),
+ std::make_shared<TBufferedTransportFactory>(),
+ std::make_shared<TBinaryProtocolFactory>(),
threadManager);
*/
diff --git a/tutorial/csharp/CsharpClient/Properties/AssemblyInfo.cs b/tutorial/csharp/CsharpClient/Properties/AssemblyInfo.cs
index 401374d..bae5e70 100644
--- a/tutorial/csharp/CsharpClient/Properties/AssemblyInfo.cs
+++ b/tutorial/csharp/CsharpClient/Properties/AssemblyInfo.cs
@@ -51,5 +51,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.12.1.0")]
-[assembly: AssemblyFileVersion("0.12.1.0")]
+[assembly: AssemblyVersion("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/tutorial/csharp/CsharpServer/Properties/AssemblyInfo.cs b/tutorial/csharp/CsharpServer/Properties/AssemblyInfo.cs
index 6067a02..e3ed39a 100644
--- a/tutorial/csharp/CsharpServer/Properties/AssemblyInfo.cs
+++ b/tutorial/csharp/CsharpServer/Properties/AssemblyInfo.cs
@@ -51,5 +51,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.12.1.0")]
-[assembly: AssemblyFileVersion("0.12.1.0")]
+[assembly: AssemblyVersion("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/tutorial/d/Makefile.am b/tutorial/d/Makefile.am
index d8c8b29..358294c 100644
--- a/tutorial/d/Makefile.am
+++ b/tutorial/d/Makefile.am
@@ -44,3 +44,10 @@
clean:
$(RM) -f $(PROGS)
+ $(RM) -r gen-d/
+ find . -type f -name '*.o' | xargs rm -f
+
+dist-hook:
+ $(RM) -f $(distdir)/$(PROGS)
+ $(RM) -r $(distdir)/gen-d/
+ find $(destdir) -type f -name '*.o' | xargs rm -f
diff --git a/tutorial/dart/Makefile.am b/tutorial/dart/Makefile.am
index 0495aca..0b93ac8 100644
--- a/tutorial/dart/Makefile.am
+++ b/tutorial/dart/Makefile.am
@@ -25,11 +25,19 @@
all-local: gen-dart/tutorial/lib/tutorial.dart pub-get
clean-local:
- $(RM) -r gen-*
+ $(RM) -r gen-*/
+ find . -type d -name ".dart_tool" | xargs $(RM) -r
find . -type d -name "packages" | xargs $(RM) -r
find . -type f -name ".packages" | xargs $(RM)
find . -type f -name "pubspec.lock" | xargs $(RM)
+dist-hook:
+ $(RM) -r $(distdir)/gen-*/
+ find $(distdir) -type d -name ".dart_tool" | xargs $(RM) -r
+ find $(distdir) -type d -name "packages" | xargs $(RM) -r
+ find $(distdir) -type f -name ".packages" | xargs $(RM)
+ find $(distdir) -type f -name "pubspec.lock" | xargs $(RM)
+
pub-get: pub-get-gen pub-get-client pub-get-console-client pub-get-server
pub-get-gen: pub-get-tutorial pub-get-shared
diff --git a/tutorial/dart/client/pubspec.yaml b/tutorial/dart/client/pubspec.yaml
index 5a0bcf8..6581b4d 100644
--- a/tutorial/dart/client/pubspec.yaml
+++ b/tutorial/dart/client/pubspec.yaml
@@ -16,16 +16,15 @@
# under the License.
name: tutorial_client
-version: 0.12.1
+version: 0.13.0
description: A Dart client implementation of the Apache Thrift tutorial
author: Apache Thrift Developers <dev@thrift.apache.org>
homepage: http://thrift.apache.org
environment:
- sdk: ">=1.13.0 <2.0.0"
+ sdk: ">=1.13.0 <3.0.0"
dependencies:
- browser: ^0.10.0
shared:
path: ../gen-dart/shared
thrift:
diff --git a/tutorial/dart/client/web/index.html b/tutorial/dart/client/web/index.html
index 64b184e..9d36b43 100644
--- a/tutorial/dart/client/web/index.html
+++ b/tutorial/dart/client/web/index.html
@@ -24,8 +24,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thrift Tutorial</title>
<link rel="stylesheet" href="styles.css">
- <script async src="client.dart" type="application/dart"></script>
- <script async src="packages/browser/dart.js"></script>
+ <script async src="client.dart.js"></script>
</head>
<body>
diff --git a/tutorial/dart/console_client/pubspec.yaml b/tutorial/dart/console_client/pubspec.yaml
index 710d4de..ca122d2 100644
--- a/tutorial/dart/console_client/pubspec.yaml
+++ b/tutorial/dart/console_client/pubspec.yaml
@@ -16,17 +16,17 @@
# under the License.
name: tutorial_console_client
-version: 0.12.1
+version: 0.13.0
description: >
A Dart console client to implementation of the Apache Thrift tutorial
author: Apache Thrift Developers <dev@thrift.apache.org>
homepage: http://thrift.apache.org
environment:
- sdk: ">=1.13.0 <2.0.0"
+ sdk: ">=1.13.0 <3.0.0"
dependencies:
- args: ^0.13.0
+ args: ">=0.13.0 <2.0.0"
collection: ^1.1.0
shared:
path: ../gen-dart/shared
diff --git a/tutorial/dart/server/pubspec.yaml b/tutorial/dart/server/pubspec.yaml
index e9cb938..e09465e 100644
--- a/tutorial/dart/server/pubspec.yaml
+++ b/tutorial/dart/server/pubspec.yaml
@@ -16,16 +16,16 @@
# under the License.
name: tutorial_server
-version: 0.12.1
+version: 0.13.0
description: A Dart server to support the Apache Thrift tutorial
author: Apache Thrift Developers <dev@thrift.apache.org>
homepage: http://thrift.apache.org
environment:
- sdk: ">=1.13.0 <2.0.0"
+ sdk: ">=1.13.0 <3.0.0"
dependencies:
- args: ^0.13.0
+ args: ">=0.13.0 <2.0.0"
shared:
path: ../gen-dart/shared
thrift:
diff --git a/tutorial/delphi/DelphiClient/DelphiClient.dpr b/tutorial/delphi/DelphiClient/DelphiClient.dpr
index 74d0d45..4ea9eb3 100644
--- a/tutorial/delphi/DelphiClient/DelphiClient.dpr
+++ b/tutorial/delphi/DelphiClient/DelphiClient.dpr
@@ -32,6 +32,9 @@
Thrift.Protocol in '..\..\..\lib\delphi\src\Thrift.Protocol.pas',
Thrift.Server in '..\..\..\lib\delphi\src\Thrift.Server.pas',
Thrift.Transport in '..\..\..\lib\delphi\src\Thrift.Transport.pas',
+ Thrift.Transport.WinHTTP in '..\..\..\lib\delphi\src\Thrift.Transport.WinHTTP.pas',
+ Thrift.Transport.MsxmlHTTP in '..\..\..\lib\delphi\src\Thrift.Transport.MsxmlHTTP.pas',
+ Thrift.WinHTTP in '..\..\..\lib\delphi\src\Thrift.WinHTTP.pas',
Shared in '..\..\gen-delphi\Shared.pas',
Tutorial in '..\..\gen-delphi\Tutorial.pas';
diff --git a/tutorial/delphi/DelphiClient/DelphiClient.dproj b/tutorial/delphi/DelphiClient/DelphiClient.dproj
index 1d669ce..7026747 100644
--- a/tutorial/delphi/DelphiClient/DelphiClient.dproj
+++ b/tutorial/delphi/DelphiClient/DelphiClient.dproj
@@ -58,6 +58,9 @@
<DCCReference Include="..\..\..\lib\delphi\src\Thrift.Protocol.pas"/>
<DCCReference Include="..\..\..\lib\delphi\src\Thrift.Server.pas"/>
<DCCReference Include="..\..\..\lib\delphi\src\Thrift.Transport.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Transport.WinHTTP.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Transport.MsxmlHTTP.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.WinHTTP.pas"/>
<DCCReference Include="..\..\gen-delphi\Shared.pas"/>
<DCCReference Include="..\..\gen-delphi\Tutorial.pas"/>
<BuildConfiguration Include="Release">
@@ -97,13 +100,13 @@
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription">Thrift Tutorial</VersionInfoKeys>
- <VersionInfoKeys Name="FileVersion">0.12.1.0</VersionInfoKeys>
+ <VersionInfoKeys Name="FileVersion">0.13.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName">DelphiClient</VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright">Copyright © 2012 The Apache Software Foundation</VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename">DelphiClient.exe</VersionInfoKeys>
<VersionInfoKeys Name="ProductName">Thrift</VersionInfoKeys>
- <VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="ProductVersion">0.13.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
<Source>
diff --git a/tutorial/delphi/DelphiServer/DelphiServer.dpr b/tutorial/delphi/DelphiServer/DelphiServer.dpr
index 5f42e7e..fc9997a 100644
--- a/tutorial/delphi/DelphiServer/DelphiServer.dpr
+++ b/tutorial/delphi/DelphiServer/DelphiServer.dpr
@@ -34,6 +34,7 @@
Thrift.Protocol in '..\..\..\lib\delphi\src\Thrift.Protocol.pas',
Thrift.Server in '..\..\..\lib\delphi\src\Thrift.Server.pas',
Thrift.Transport in '..\..\..\lib\delphi\src\Thrift.Transport.pas',
+ Thrift.WinHTTP in '..\..\..\lib\delphi\src\Thrift.WinHTTP.pas',
Shared in '..\..\gen-delphi\Shared.pas',
Tutorial in '..\..\gen-delphi\Tutorial.pas';
diff --git a/tutorial/delphi/DelphiServer/DelphiServer.dproj b/tutorial/delphi/DelphiServer/DelphiServer.dproj
index 62aa891..ec1da2e 100644
--- a/tutorial/delphi/DelphiServer/DelphiServer.dproj
+++ b/tutorial/delphi/DelphiServer/DelphiServer.dproj
@@ -57,6 +57,7 @@
<DCCReference Include="..\..\..\lib\delphi\src\Thrift.Protocol.pas"/>
<DCCReference Include="..\..\..\lib\delphi\src\Thrift.Server.pas"/>
<DCCReference Include="..\..\..\lib\delphi\src\Thrift.Transport.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.WinHTTP.pas"/>
<DCCReference Include="..\..\gen-delphi\Shared.pas"/>
<DCCReference Include="..\..\gen-delphi\Tutorial.pas"/>
<BuildConfiguration Include="Release">
@@ -96,13 +97,13 @@
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription">Thrift Tutorial</VersionInfoKeys>
- <VersionInfoKeys Name="FileVersion">0.12.1.0</VersionInfoKeys>
+ <VersionInfoKeys Name="FileVersion">0.13.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName">DelphiServer</VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright">Copyright © 2012 The Apache Software Foundation</VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename">DelphiServer.exe</VersionInfoKeys>
<VersionInfoKeys Name="ProductName">Thrift</VersionInfoKeys>
- <VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="ProductVersion">0.13.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
<Source>
diff --git a/tutorial/erl/server.sh b/tutorial/erl/server.sh
deleted file mode 120000
index 26b3c58..0000000
--- a/tutorial/erl/server.sh
+++ /dev/null
@@ -1 +0,0 @@
-client.sh
\ No newline at end of file
diff --git a/compiler/cpp/test/cpp_plugin_test.sh b/tutorial/erl/server.sh
similarity index 63%
copy from compiler/cpp/test/cpp_plugin_test.sh
copy to tutorial/erl/server.sh
index ddb2e0a..775afb6 100755
--- a/compiler/cpp/test/cpp_plugin_test.sh
+++ b/tutorial/erl/server.sh
@@ -19,9 +19,19 @@
# under the License.
#
-# this file is intended to be invoked by make.
-set -e
-mkdir -p gen-cpp gen-mycpp
-PATH=.:"$PATH" ../thrift -r -out gen-cpp -gen cpp ../../../test/Include.thrift
-PATH=.:"$PATH" ../thrift -r -out gen-mycpp -gen mycpp ../../../test/Include.thrift
-diff -urN gen-cpp gen-mycpp
+ERL_THRIFT=../../lib/erl
+
+if ! [ -d ${ERL_THRIFT}/ebin ]; then
+ echo "Please build the Thrift library by running \`make' in ${ERL_THRIFT}"
+ exit 1
+fi
+
+if ! [ -d gen-erl ]; then
+ ../../compiler/cpp/thrift -r --gen erl ../tutorial.thrift
+fi
+
+
+erlc -I ${ERL_THRIFT}/include -I ${ERL_THRIFT}/ebin \
+ -I gen-erl -o gen-erl gen-erl/*.erl &&
+ erlc -I ${ERL_THRIFT}/include -I gen-erl *.erl &&
+ erl +K true -pa ${ERL_THRIFT}/ebin -pa gen-erl
diff --git a/tutorial/hs/Makefile.am b/tutorial/hs/Makefile.am
index a3eccc2..9c6fd83 100755
--- a/tutorial/hs/Makefile.am
+++ b/tutorial/hs/Makefile.am
@@ -27,7 +27,12 @@
# Make sure this doesn't fail if Haskell is not configured.
clean-local:
$(CABAL) clean
- $(RM) -r gen-*
+ $(RM) -r dist/
+ $(RM) -r gen-*/
+
+dist-hook:
+ $(RM) -r $(distdir)/dist/
+ $(RM) -r $(distdir)/gen-*/
check-local:
$(CABAL) check
diff --git a/tutorial/hs/ThriftTutorial.cabal b/tutorial/hs/ThriftTutorial.cabal
index 40617a1..b6a6122 100755
--- a/tutorial/hs/ThriftTutorial.cabal
+++ b/tutorial/hs/ThriftTutorial.cabal
@@ -18,7 +18,7 @@
--
Name: ThriftTutorial
-Version: 0.12.1
+Version: 0.13.0
Cabal-Version: >= 1.4
License: OtherLicense
Category: Foreign
diff --git a/tutorial/js/tutorial.html b/tutorial/js/tutorial.html
index d7f3945..d020bed 100755
--- a/tutorial/js/tutorial.html
+++ b/tutorial/js/tutorial.html
@@ -98,7 +98,7 @@
</table>
</form>
- <p>This Java Script example uses <a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=tutorial/tutorial.thrift;hb=HEAD">tutorial.thrift</a> and a Thrift server using JSON protocol and HTTP transport.
+ <p>This Java Script example uses <a href="https://github.com/apache/thrift/blob/master/tutorial/tutorial.thrift">tutorial.thrift</a> and a Thrift server using JSON protocol and HTTP transport.
</p>
<p>
<a href="http://validator.w3.org/check/referer"><img
diff --git a/tutorial/netcore/Makefile.am b/tutorial/netcore/Makefile.am
index e305556..bd19dfe 100644
--- a/tutorial/netcore/Makefile.am
+++ b/tutorial/netcore/Makefile.am
@@ -31,6 +31,15 @@
$(RM) -r Interfaces/bin
$(RM) -r Interfaces/obj
+dist-hook:
+ $(RM) $(distdir)/Interfaces.dll
+ $(RM) -r $(distdir)/Client/bin
+ $(RM) -r $(distdir)/Client/obj
+ $(RM) -r $(distdir)/Server/bin
+ $(RM) -r $(distdir)/Server/obj
+ $(RM) -r $(distdir)/Interfaces/bin
+ $(RM) -r $(distdir)/Interfaces/obj
+
EXTRA_DIST = \
Client \
Interfaces \
diff --git a/tutorial/netstd/.gitignore b/tutorial/netstd/.gitignore
new file mode 100644
index 0000000..9938bb2
--- /dev/null
+++ b/tutorial/netstd/.gitignore
@@ -0,0 +1 @@
+!**/*.pfx
\ No newline at end of file
diff --git a/tutorial/netstd/Client/Client.csproj b/tutorial/netstd/Client/Client.csproj
new file mode 100644
index 0000000..a1470a9
--- /dev/null
+++ b/tutorial/netstd/Client/Client.csproj
@@ -0,0 +1,41 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <!--
+ 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.
+ -->
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ <AssemblyName>Client</AssemblyName>
+ <PackageId>Client</PackageId>
+ <OutputType>Exe</OutputType>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Interfaces\Interfaces.csproj" />
+ <ProjectReference Include="..\..\..\lib\netstd\Thrift\Thrift.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/tutorial/netstd/Client/Program.cs b/tutorial/netstd/Client/Program.cs
new file mode 100644
index 0000000..f9509fa
--- /dev/null
+++ b/tutorial/netstd/Client/Program.cs
@@ -0,0 +1,409 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Thrift;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+using tutorial;
+using shared;
+using Microsoft.Extensions.DependencyInjection;
+using System.Diagnostics;
+
+namespace Client
+{
+ public class Program
+ {
+ private static ServiceCollection ServiceCollection = new ServiceCollection();
+ private static ILogger Logger;
+
+ private static void DisplayHelp()
+ {
+ Logger.LogInformation(@"
+Usage:
+ Client.exe -help
+ will diplay help information
+
+ Client.exe -tr:<transport> -bf:<buffering> -pr:<protocol> -mc:<numClients>
+ will run client with specified arguments (tcp transport and binary protocol by default) and with 1 client
+
+Options:
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (address - ""http://localhost:9090"")
+ tcptls - tcp tls transport will be used (host - ""localhost"", port - 9090)
+
+ -bf (buffering):
+ none - (default) no buffering will be used
+ buffered - buffered transport will be used
+ framed - framed transport will be used
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+ multiplexed - multiplexed protocol will be used
+
+ -mc (multiple clients):
+ <numClients> - number of multiple clients to connect to server (max 100, default 1)
+
+Sample:
+ Client.exe -tr:tcp -p:binary
+");
+ }
+
+ public static void Main(string[] args)
+ {
+ args = args ?? new string[0];
+
+ ServiceCollection.AddLogging(logging => ConfigureLogging(logging));
+ Logger = ServiceCollection.BuildServiceProvider().GetService<ILoggerFactory>().CreateLogger(nameof(Client));
+
+ if (args.Any(x => x.StartsWith("-help", StringComparison.OrdinalIgnoreCase)))
+ {
+ DisplayHelp();
+ return;
+ }
+
+ Logger.LogInformation("Starting client...");
+
+ using (var source = new CancellationTokenSource())
+ {
+ RunAsync(args, source.Token).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void ConfigureLogging(ILoggingBuilder logging)
+ {
+ logging.SetMinimumLevel(LogLevel.Trace);
+ logging.AddConsole();
+ logging.AddDebug();
+ }
+
+ private static async Task RunAsync(string[] args, CancellationToken cancellationToken)
+ {
+ var numClients = GetNumberOfClients(args);
+
+ Logger.LogInformation($"Selected # of clients: {numClients}");
+
+ var transports = new TTransport[numClients];
+ for (int i = 0; i < numClients; i++)
+ {
+ var t = GetTransport(args);
+ transports[i] = t;
+ }
+
+ Logger.LogInformation($"Selected client transport: {transports[0]}");
+
+ var protocols = new Tuple<Protocol, TProtocol>[numClients];
+ for (int i = 0; i < numClients; i++)
+ {
+ var p = GetProtocol(args, transports[i]);
+ protocols[i] = p;
+ }
+
+ Logger.LogInformation($"Selected client protocol: {protocols[0].Item1}");
+
+ var tasks = new Task[numClients];
+ for (int i = 0; i < numClients; i++)
+ {
+ var task = RunClientAsync(protocols[i], cancellationToken);
+ tasks[i] = task;
+ }
+
+ Task.WaitAll(tasks);
+
+ await Task.CompletedTask;
+ }
+
+ private static TTransport GetTransport(string[] args)
+ {
+ TTransport transport = new TSocketTransport(IPAddress.Loopback, 9090);
+
+ // construct endpoint transport
+ var transportArg = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1];
+ if (Enum.TryParse(transportArg, true, out Transport selectedTransport))
+ {
+ switch (selectedTransport)
+ {
+ case Transport.Tcp:
+ transport = new TSocketTransport(IPAddress.Loopback, 9090);
+ break;
+
+ case Transport.NamedPipe:
+ transport = new TNamedPipeTransport(".test");
+ break;
+
+ case Transport.Http:
+ transport = new THttpTransport(new Uri("http://localhost:9090"), null);
+ break;
+
+ case Transport.TcpTls:
+ transport = new TTlsSocketTransport(IPAddress.Loopback, 9090, GetCertificate(), CertValidator, LocalCertificateSelectionCallback);
+ break;
+
+ default:
+ Debug.Assert(false, "unhandled case");
+ break;
+ }
+ }
+
+ // optionally add layered transport(s)
+ var bufferingArg = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(':')?[1];
+ if (Enum.TryParse<Buffering>(bufferingArg, out var selectedBuffering))
+ {
+ switch (selectedBuffering)
+ {
+ case Buffering.Buffered:
+ transport = new TBufferedTransport(transport);
+ break;
+
+ case Buffering.Framed:
+ transport = new TFramedTransport(transport);
+ break;
+
+ default: // layered transport(s) are optional
+ Debug.Assert(selectedBuffering == Buffering.None, "unhandled case");
+ break;
+ }
+ }
+
+ return transport;
+ }
+
+ private static int GetNumberOfClients(string[] args)
+ {
+ var numClients = args.FirstOrDefault(x => x.StartsWith("-mc"))?.Split(':')?[1];
+
+ Logger.LogInformation($"Selected # of clients: {numClients}");
+
+ int c;
+ if( int.TryParse(numClients, out c) && (0 < c) && (c <= 100))
+ return c;
+ else
+ return 1;
+ }
+
+ private static X509Certificate2 GetCertificate()
+ {
+ // due to files location in net core better to take certs from top folder
+ var certFile = GetCertPath(Directory.GetParent(Directory.GetCurrentDirectory()));
+ return new X509Certificate2(certFile, "ThriftTest");
+ }
+
+ private static string GetCertPath(DirectoryInfo di, int maxCount = 6)
+ {
+ var topDir = di;
+ var certFile =
+ topDir.EnumerateFiles("ThriftTest.pfx", SearchOption.AllDirectories)
+ .FirstOrDefault();
+ if (certFile == null)
+ {
+ if (maxCount == 0)
+ throw new FileNotFoundException("Cannot find file in directories");
+ return GetCertPath(di.Parent, maxCount - 1);
+ }
+
+ return certFile.FullName;
+ }
+
+ private static X509Certificate LocalCertificateSelectionCallback(object sender,
+ string targetHost, X509CertificateCollection localCertificates,
+ X509Certificate remoteCertificate, string[] acceptableIssuers)
+ {
+ return GetCertificate();
+ }
+
+ private static bool CertValidator(object sender, X509Certificate certificate,
+ X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ {
+ return true;
+ }
+
+ private static Tuple<Protocol, TProtocol> GetProtocol(string[] args, TTransport transport)
+ {
+ var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1];
+
+ Protocol selectedProtocol;
+ if (Enum.TryParse(protocol, true, out selectedProtocol))
+ {
+ switch (selectedProtocol)
+ {
+ case Protocol.Binary:
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
+ case Protocol.Compact:
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TCompactProtocol(transport));
+ case Protocol.Json:
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TJsonProtocol(transport));
+ case Protocol.Multiplexed:
+ // it returns BinaryProtocol to avoid making wrapped protocol as public in TProtocolDecorator (in RunClientAsync it will be wrapped into Multiplexed protocol)
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
+ default:
+ Debug.Assert(false, "unhandled case");
+ break;
+ }
+ }
+
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
+ }
+
+ private static async Task RunClientAsync(Tuple<Protocol, TProtocol> protocolTuple, CancellationToken cancellationToken)
+ {
+ try
+ {
+ var protocol = protocolTuple.Item2;
+ var protocolType = protocolTuple.Item1;
+
+ TBaseClient client = null;
+
+ try
+ {
+ if (protocolType != Protocol.Multiplexed)
+ {
+
+ client = new Calculator.Client(protocol);
+ await ExecuteCalculatorClientOperations(cancellationToken, (Calculator.Client)client);
+ }
+ else
+ {
+ // it uses binary protocol there to create Multiplexed protocols
+ var multiplex = new TMultiplexedProtocol(protocol, nameof(Calculator));
+ client = new Calculator.Client(multiplex);
+ await ExecuteCalculatorClientOperations(cancellationToken, (Calculator.Client)client);
+
+ multiplex = new TMultiplexedProtocol(protocol, nameof(SharedService));
+ client = new SharedService.Client(multiplex);
+ await ExecuteSharedServiceClientOperations(cancellationToken, (SharedService.Client)client);
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError($"{client?.ClientId} " + ex);
+ }
+ finally
+ {
+ protocol.Transport.Close();
+ }
+ }
+ catch (TApplicationException x)
+ {
+ Logger.LogError(x.ToString());
+ }
+ }
+
+ private static async Task ExecuteCalculatorClientOperations(CancellationToken cancellationToken, Calculator.Client client)
+ {
+ await client.OpenTransportAsync(cancellationToken);
+
+ // Async version
+
+ Logger.LogInformation($"{client.ClientId} PingAsync()");
+ await client.pingAsync(cancellationToken);
+
+ Logger.LogInformation($"{client.ClientId} AddAsync(1,1)");
+ var sum = await client.addAsync(1, 1, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} AddAsync(1,1)={sum}");
+
+ var work = new Work
+ {
+ Op = Operation.DIVIDE,
+ Num1 = 1,
+ Num2 = 0
+ };
+
+ try
+ {
+ Logger.LogInformation($"{client.ClientId} CalculateAsync(1)");
+ await client.calculateAsync(1, work, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} Whoa we can divide by 0");
+ }
+ catch (InvalidOperation io)
+ {
+ Logger.LogInformation($"{client.ClientId} Invalid operation: " + io);
+ }
+
+ work.Op = Operation.SUBTRACT;
+ work.Num1 = 15;
+ work.Num2 = 10;
+
+ try
+ {
+ Logger.LogInformation($"{client.ClientId} CalculateAsync(1)");
+ var diff = await client.calculateAsync(1, work, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} 15-10={diff}");
+ }
+ catch (InvalidOperation io)
+ {
+ Logger.LogInformation($"{client.ClientId} Invalid operation: " + io);
+ }
+
+ Logger.LogInformation($"{client.ClientId} GetStructAsync(1)");
+ var log = await client.getStructAsync(1, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} Check log: {log.Value}");
+
+ Logger.LogInformation($"{client.ClientId} ZipAsync() with delay 100mc on server side");
+ await client.zipAsync(cancellationToken);
+ }
+ private static async Task ExecuteSharedServiceClientOperations(CancellationToken cancellationToken, SharedService.Client client)
+ {
+ await client.OpenTransportAsync(cancellationToken);
+
+ // Async version
+
+ Logger.LogInformation($"{client.ClientId} SharedService GetStructAsync(1)");
+ var log = await client.getStructAsync(1, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} SharedService Value: {log.Value}");
+ }
+
+
+ private enum Transport
+ {
+ Tcp,
+ NamedPipe,
+ Http,
+ TcpBuffered,
+ Framed,
+ TcpTls
+ }
+
+ private enum Protocol
+ {
+ Binary,
+ Compact,
+ Json,
+ Multiplexed
+ }
+
+ private enum Buffering
+ {
+ None,
+ Buffered,
+ Framed
+ }
+ }
+}
diff --git a/tutorial/netstd/Client/Properties/AssemblyInfo.cs b/tutorial/netstd/Client/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..568382e
--- /dev/null
+++ b/tutorial/netstd/Client/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// 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.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("de78a01b-f7c6-49d1-97da-669d2ed37641")]
\ No newline at end of file
diff --git a/tutorial/netstd/Client/Properties/launchSettings.json b/tutorial/netstd/Client/Properties/launchSettings.json
new file mode 100644
index 0000000..6b7b60d
--- /dev/null
+++ b/tutorial/netstd/Client/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "Client": {
+ "commandName": "Project",
+ "commandLineArgs": "-p:multiplexed"
+ }
+ }
+}
\ No newline at end of file
diff --git a/tutorial/netstd/Client/ThriftTest.pfx b/tutorial/netstd/Client/ThriftTest.pfx
new file mode 100644
index 0000000..f0ded28
--- /dev/null
+++ b/tutorial/netstd/Client/ThriftTest.pfx
Binary files differ
diff --git a/tutorial/netstd/Interfaces/.gitignore b/tutorial/netstd/Interfaces/.gitignore
new file mode 100644
index 0000000..2e7446e
--- /dev/null
+++ b/tutorial/netstd/Interfaces/.gitignore
@@ -0,0 +1,3 @@
+# ignore for autogenerated files
+/shared
+/tutorial
diff --git a/tutorial/netstd/Interfaces/Interfaces.csproj b/tutorial/netstd/Interfaces/Interfaces.csproj
new file mode 100644
index 0000000..4ebeb4f
--- /dev/null
+++ b/tutorial/netstd/Interfaces/Interfaces.csproj
@@ -0,0 +1,48 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <!--
+ 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.
+ -->
+
+ <PropertyGroup>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ <AssemblyName>Interfaces</AssemblyName>
+ <PackageId>Interfaces</PackageId>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../../../lib/netstd/Thrift/Thrift.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="System.ServiceModel.Primitives" Version="4.5.3" />
+ </ItemGroup>
+
+ <Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
+ <Exec Condition="'$(OS)' == 'Windows_NT'" Command="where thrift" ConsoleToMSBuild="true">
+ <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" />
+ </Exec>
+ <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../tutorial.thrift" />
+ <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../tutorial.thrift" />
+ <Exec Condition="Exists('./../../../compiler/cpp/thrift')" Command="./../../../compiler/cpp/thrift -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../tutorial.thrift" />
+ </Target>
+
+</Project>
diff --git a/tutorial/netstd/Interfaces/Properties/AssemblyInfo.cs b/tutorial/netstd/Interfaces/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9126b17
--- /dev/null
+++ b/tutorial/netstd/Interfaces/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// 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.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("4d13163d-9067-4c9c-8af0-64e08451397d")]
\ No newline at end of file
diff --git a/compiler/cpp/test/cpp_plugin_test.sh b/tutorial/netstd/Makefile.am
old mode 100755
new mode 100644
similarity index 70%
copy from compiler/cpp/test/cpp_plugin_test.sh
copy to tutorial/netstd/Makefile.am
index ddb2e0a..e305556
--- a/compiler/cpp/test/cpp_plugin_test.sh
+++ b/tutorial/netstd/Makefile.am
@@ -1,5 +1,3 @@
-#!/bin/sh
-
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -19,9 +17,26 @@
# under the License.
#
-# this file is intended to be invoked by make.
-set -e
-mkdir -p gen-cpp gen-mycpp
-PATH=.:"$PATH" ../thrift -r -out gen-cpp -gen cpp ../../../test/Include.thrift
-PATH=.:"$PATH" ../thrift -r -out gen-mycpp -gen mycpp ../../../test/Include.thrift
-diff -urN gen-cpp gen-mycpp
+SUBDIRS = .
+
+all-local:
+ $(DOTNETCORE) build
+
+clean-local:
+ $(RM) Interfaces.dll
+ $(RM) -r Client/bin
+ $(RM) -r Client/obj
+ $(RM) -r Server/bin
+ $(RM) -r Server/obj
+ $(RM) -r Interfaces/bin
+ $(RM) -r Interfaces/obj
+
+EXTRA_DIST = \
+ Client \
+ Interfaces \
+ README.md \
+ Server \
+ Tutorial.sln \
+ build.cmd \
+ build.sh
+
diff --git a/tutorial/netstd/README.md b/tutorial/netstd/README.md
new file mode 100644
index 0000000..b1dea4e
--- /dev/null
+++ b/tutorial/netstd/README.md
@@ -0,0 +1,284 @@
+# Building of samples for different platforms
+
+# Reused components
+- NET Core Standard 2.0
+- NET Core App 2.0
+
+# How to build
+- Download and install the latest .NET Core SDK for your platform https://www.microsoft.com/net/core#windowsvs2015 (archive for SDK 1.0.0-preview2-003121 located by: https://github.com/dotnet/core/blob/master/release-notes/download-archive.md)
+- Ensure that you have thrift.exe which supports netstd lib and it added to PATH
+- Go to current folder
+- Run **build.sh** or **build.cmd** from the root of cloned repository
+- Check tests in **src/Tests** folder
+- Continue with /tutorials/netstd
+
+# How to run
+
+Notes: dotnet run supports passing arguments to app after -- symbols (https://docs.microsoft.com/en-us/dotnet/articles/core/tools/dotnet-run) - example: **dotnet run -- -h** will show help for app
+
+- build
+- go to folder (Client/Server)
+- run with specifying of correct parameters **dotnet run -tr:tcp -pr:multiplexed**, **dotnet run -help** (later, after migration to csproj and latest SDK will be possibility to use more usable form **dotnet run -- arguments**)
+
+#Notes
+- Possible adding additional platforms after stabilization of .NET Core (runtimes, platforms (Red Hat Linux, OpenSuse, etc.)
+
+#Known issues
+- In trace logging mode you can see some not important internal exceptions
+
+# Running of samples
+Please install Thrift C# .NET Core library or copy sources and build them to correcly build and run samples
+
+# NetCore Server
+
+Usage:
+
+ Server.exe -h
+ will diplay help information
+
+ Server.exe -tr:<transport> -pr:<protocol>
+ will run server with specified arguments (tcp transport and binary protocol by default)
+
+Options:
+
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (http address - ""localhost:9090"")
+ tcptls - tcp transport with tls will be used (host - ""localhost"", port - 9090)
+
+ -bf (buffering):
+ none - (default) no transport factory will be used
+ buffered - buffered transport factory will be used
+ framed - framed transport factory will be used (this must match the client)
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+
+Sample:
+
+ Server.exe -tr:tcp
+
+**Remarks**:
+
+ For TcpTls mode certificate's file ThriftTest.pfx should be in directory with binaries in case of command line usage (or at project level in case of debugging from IDE).
+ Password for certificate - "ThriftTest".
+
+
+
+# NetCore Client
+
+Usage:
+
+ Client.exe -h
+ will diplay help information
+
+ Client.exe -tr:<transport> -pr:<protocol> -mc:<numClients>
+ will run client with specified arguments (tcp transport and binary protocol by default)
+
+Options:
+
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (address - ""http://localhost:9090"")
+ tcptls - tcp tls transport will be used (host - ""localhost"", port - 9090)
+
+ -bf (buffering):
+ none - (default) no transport factory will be used
+ buffered - buffered transport factory will be used
+ framed - framed transport factory will be used (this must match the client)
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+
+ -mc (multiple clients):
+ <numClients> - number of multiple clients to connect to server (max 100, default 1)
+
+Sample:
+
+ Client.exe -tr:tcp -pr:binary -mc:10
+
+Remarks:
+
+ For TcpTls mode certificate's file ThriftTest.pfx should be in directory
+ with binaries in case of command line usage (or at project level in case of debugging from IDE).
+ Password for certificate - "ThriftTest".
+
+# How to test communication between NetCore and Python
+
+* Generate code with the latest **thrift.exe** util
+* Ensure that **thrift.exe** util generated folder **gen-py** with generated code for Python
+* Create **client.py** and **server.py** from the code examples below and save them to the folder with previosly generated folder **gen-py**
+* Run netstd samples (client and server) and python samples (client and server)
+
+Remarks:
+
+Samples of client and server code below use correct methods (operations)
+and fields (properties) according to generated contracts from *.thrift files
+
+At Windows 10 add record **127.0.0.1 testserver** to **C:\Windows\System32\drivers\etc\hosts** file
+for correct work of python server
+
+
+**Python Client:**
+
+```python
+import sys
+import glob
+sys.path.append('gen-py')
+
+from tutorial import Calculator
+from tutorial.ttypes import InvalidOperation, Operation, Work
+
+from thrift import Thrift
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+
+
+def main():
+ # Make socket
+ transport = TSocket.TSocket('127.0.0.1', 9090)
+
+ # Buffering is critical. Raw sockets are very slow
+ transport = TTransport.TBufferedTransport(transport)
+
+ # Wrap in a protocol
+ protocol = TBinaryProtocol.TBinaryProtocol(transport)
+
+ # Create a client to use the protocol encoder
+ client = Calculator.Client(protocol)
+
+ # Connect!
+ transport.open()
+
+ client.Ping()
+ print('ping()')
+
+ sum = client.Add(1, 1)
+ print(('1+1=%d' % (sum)))
+
+ work = Work()
+
+ work.Op = Operation.Divide
+ work.Num1 = 1
+ work.Num2 = 0
+
+ try:
+ quotient = client.Calculate(1, work)
+ print('Whoa? You know how to divide by zero?')
+ print('FYI the answer is %d' % quotient)
+ except InvalidOperation as e:
+ print(('InvalidOperation: %r' % e))
+
+ work.Op = Operation.Substract
+ work.Num1 = 15
+ work.Num2 = 10
+
+ diff = client.Calculate(1, work)
+ print(('15-10=%d' % (diff)))
+
+ log = client.GetStruct(1)
+ print(('Check log: %s' % (log.Value)))
+
+ client.Zip()
+ print('zip()')
+
+ # Close!
+ transport.close()
+
+if __name__ == '__main__':
+ try:
+ main()
+ except Thrift.TException as tx:
+ print('%s' % tx.message)
+```
+
+
+**Python Server:**
+
+
+```python
+import glob
+import sys
+sys.path.append('gen-py')
+
+from tutorial import Calculator
+from tutorial.ttypes import InvalidOperation, Operation
+
+from shared.ttypes import SharedStruct
+
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+from thrift.server import TServer
+
+
+class CalculatorHandler:
+ def __init__(self):
+ self.log = {}
+
+ def Ping(self):
+ print('ping()')
+
+ def Add(self, n1, n2):
+ print('add(%d,%d)' % (n1, n2))
+ return n1 + n2
+
+ def Calculate(self, logid, work):
+ print('calculate(%d, %r)' % (logid, work))
+
+ if work.Op == Operation.Add:
+ val = work.Num1 + work.Num2
+ elif work.Op == Operation.Substract:
+ val = work.Num1 - work.Num2
+ elif work.Op == Operation.Multiply:
+ val = work.Num1 * work.Num2
+ elif work.Op == Operation.Divide:
+ if work.Num2 == 0:
+ x = InvalidOperation()
+ x.WhatOp = work.Op
+ x.Why = 'Cannot divide by 0'
+ raise x
+ val = work.Num1 / work.Num2
+ else:
+ x = InvalidOperation()
+ x.WhatOp = work.Op
+ x.Why = 'Invalid operation'
+ raise x
+
+ log = SharedStruct()
+ log.Key = logid
+ log.Value = '%d' % (val)
+ self.log[logid] = log
+
+ return val
+
+ def GetStruct(self, key):
+ print('getStruct(%d)' % (key))
+ return self.log[key]
+
+ def Zip(self):
+ print('zip()')
+
+if __name__ == '__main__':
+ handler = CalculatorHandler()
+ processor = Calculator.Processor(handler)
+ transport = TSocket.TServerSocket(host="testserver", port=9090)
+ tfactory = TTransport.TBufferedTransportFactory()
+ pfactory = TBinaryProtocol.TBinaryProtocolFactory()
+
+ server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
+ print('Starting the server...')
+ server.serve()
+ print('done.')
+
+ # You could do one of these for a multithreaded server
+ # server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
+ # server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
+```
diff --git a/tutorial/netstd/Server/Program.cs b/tutorial/netstd/Server/Program.cs
new file mode 100644
index 0000000..25e7dae
--- /dev/null
+++ b/tutorial/netstd/Server/Program.cs
@@ -0,0 +1,479 @@
+// 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.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Thrift;
+using Thrift.Protocol;
+using Thrift.Server;
+using Thrift.Transport;
+using Thrift.Transport.Server;
+using tutorial;
+using shared;
+using Thrift.Processor;
+using System.Diagnostics;
+
+namespace Server
+{
+ public class Program
+ {
+ private static ServiceCollection ServiceCollection = new ServiceCollection();
+ private static ILogger Logger;
+
+ public static void Main(string[] args)
+ {
+ args = args ?? new string[0];
+
+ ServiceCollection.AddLogging(logging => ConfigureLogging(logging));
+ Logger = ServiceCollection.BuildServiceProvider().GetService<ILoggerFactory>().CreateLogger(nameof(Server));
+
+
+ if (args.Any(x => x.StartsWith("-help", StringComparison.OrdinalIgnoreCase)))
+ {
+ DisplayHelp();
+ return;
+ }
+
+ using (var source = new CancellationTokenSource())
+ {
+ RunAsync(args, source.Token).GetAwaiter().GetResult();
+
+ Logger.LogInformation("Press any key to stop...");
+
+ Console.ReadLine();
+ source.Cancel();
+ }
+
+ Logger.LogInformation("Server stopped");
+ }
+
+ private static void ConfigureLogging(ILoggingBuilder logging)
+ {
+ logging.SetMinimumLevel(LogLevel.Trace);
+ logging.AddConsole();
+ logging.AddDebug();
+ }
+
+ private static void DisplayHelp()
+ {
+ Logger.LogInformation(@"
+Usage:
+ Server.exe -help
+ will diplay help information
+
+ Server.exe -tr:<transport> -bf:<buffering> -pr:<protocol>
+ will run server with specified arguments (tcp transport, no buffering, and binary protocol by default)
+
+Options:
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (http address - ""localhost:9090"")
+ tcptls - tcp transport with tls will be used (host - ""localhost"", port - 9090)
+
+ -bf (buffering):
+ none - (default) no buffering will be used
+ buffered - buffered transport will be used
+ framed - framed transport will be used
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+ multiplexed - multiplexed protocol will be used
+
+Sample:
+ Server.exe -tr:tcp
+");
+ }
+
+ private static async Task RunAsync(string[] args, CancellationToken cancellationToken)
+ {
+ var selectedTransport = GetTransport(args);
+ var selectedBuffering = GetBuffering(args);
+ var selectedProtocol = GetProtocol(args);
+
+ if (selectedTransport == Transport.Http)
+ {
+ new HttpServerSample().Run(cancellationToken);
+ }
+ else
+ {
+ await RunSelectedConfigurationAsync(selectedTransport, selectedBuffering, selectedProtocol, cancellationToken);
+ }
+ }
+
+ private static Protocol GetProtocol(string[] args)
+ {
+ var transport = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1];
+
+ Enum.TryParse(transport, true, out Protocol selectedProtocol);
+
+ return selectedProtocol;
+ }
+
+ private static Buffering GetBuffering(string[] args)
+ {
+ var buffering = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(":")?[1];
+
+ Enum.TryParse<Buffering>(buffering, out var selectedBuffering);
+
+ return selectedBuffering;
+ }
+
+ private static Transport GetTransport(string[] args)
+ {
+ var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1];
+
+ Enum.TryParse(transport, true, out Transport selectedTransport);
+
+ return selectedTransport;
+ }
+
+ private static async Task RunSelectedConfigurationAsync(Transport transport, Buffering buffering, Protocol protocol, CancellationToken cancellationToken)
+ {
+ var handler = new CalculatorAsyncHandler();
+
+ TServerTransport serverTransport = null;
+ switch (transport)
+ {
+ case Transport.Tcp:
+ serverTransport = new TServerSocketTransport(9090);
+ break;
+ case Transport.NamedPipe:
+ serverTransport = new TNamedPipeServerTransport(".test");
+ break;
+ case Transport.TcpTls:
+ serverTransport = new TTlsServerSocketTransport(9090, GetCertificate(), ClientCertValidator, LocalCertificateSelectionCallback);
+ break;
+ }
+
+ TTransportFactory inputTransportFactory = null;
+ TTransportFactory outputTransportFactory = null;
+ switch (buffering)
+ {
+ case Buffering.Buffered:
+ inputTransportFactory = new TBufferedTransport.Factory();
+ outputTransportFactory = new TBufferedTransport.Factory();
+ break;
+
+ case Buffering.Framed:
+ inputTransportFactory = new TFramedTransport.Factory();
+ outputTransportFactory = new TFramedTransport.Factory();
+ break;
+
+ default: // layered transport(s) are optional
+ Debug.Assert(buffering == Buffering.None, "unhandled case");
+ break;
+ }
+
+ TProtocolFactory inputProtocolFactory = null;
+ TProtocolFactory outputProtocolFactory = null;
+ ITAsyncProcessor processor = null;
+ switch (protocol)
+ {
+ case Protocol.Binary:
+ inputProtocolFactory = new TBinaryProtocol.Factory();
+ outputProtocolFactory = new TBinaryProtocol.Factory();
+ processor = new Calculator.AsyncProcessor(handler);
+ break;
+
+ case Protocol.Compact:
+ inputProtocolFactory = new TCompactProtocol.Factory();
+ outputProtocolFactory = new TCompactProtocol.Factory();
+ processor = new Calculator.AsyncProcessor(handler);
+ break;
+
+ case Protocol.Json:
+ inputProtocolFactory = new TJsonProtocol.Factory();
+ outputProtocolFactory = new TJsonProtocol.Factory();
+ processor = new Calculator.AsyncProcessor(handler);
+ break;
+
+ case Protocol.Multiplexed:
+ inputProtocolFactory = new TBinaryProtocol.Factory();
+ outputProtocolFactory = new TBinaryProtocol.Factory();
+
+ var calcHandler = new CalculatorAsyncHandler();
+ var calcProcessor = new Calculator.AsyncProcessor(calcHandler);
+
+ var sharedServiceHandler = new SharedServiceAsyncHandler();
+ var sharedServiceProcessor = new SharedService.AsyncProcessor(sharedServiceHandler);
+
+ var multiplexedProcessor = new TMultiplexedProcessor();
+ multiplexedProcessor.RegisterProcessor(nameof(Calculator), calcProcessor);
+ multiplexedProcessor.RegisterProcessor(nameof(SharedService), sharedServiceProcessor);
+
+ processor = multiplexedProcessor;
+ break;
+
+ default:
+ throw new ArgumentOutOfRangeException(nameof(protocol), protocol, null);
+ }
+
+
+ try
+ {
+ Logger.LogInformation(
+ $"Selected TAsyncServer with {serverTransport} transport, {processor} processor and {inputProtocolFactory} protocol factories");
+
+ var loggerFactory = ServiceCollection.BuildServiceProvider().GetService<ILoggerFactory>();
+
+ var server = new TSimpleAsyncServer(
+ itProcessorFactory: new TSingletonProcessorFactory(processor),
+ serverTransport: serverTransport,
+ inputTransportFactory: inputTransportFactory,
+ outputTransportFactory: outputTransportFactory,
+ inputProtocolFactory: inputProtocolFactory,
+ outputProtocolFactory: outputProtocolFactory,
+ logger: loggerFactory.CreateLogger<TSimpleAsyncServer>());
+
+ Logger.LogInformation("Starting the server...");
+
+ await server.ServeAsync(cancellationToken);
+ }
+ catch (Exception x)
+ {
+ Logger.LogInformation(x.ToString());
+ }
+ }
+
+ private static X509Certificate2 GetCertificate()
+ {
+ // due to files location in net core better to take certs from top folder
+ var certFile = GetCertPath(Directory.GetParent(Directory.GetCurrentDirectory()));
+ return new X509Certificate2(certFile, "ThriftTest");
+ }
+
+ private static string GetCertPath(DirectoryInfo di, int maxCount = 6)
+ {
+ var topDir = di;
+ var certFile =
+ topDir.EnumerateFiles("ThriftTest.pfx", SearchOption.AllDirectories)
+ .FirstOrDefault();
+ if (certFile == null)
+ {
+ if (maxCount == 0)
+ throw new FileNotFoundException("Cannot find file in directories");
+ return GetCertPath(di.Parent, maxCount - 1);
+ }
+
+ return certFile.FullName;
+ }
+
+ private static X509Certificate LocalCertificateSelectionCallback(object sender,
+ string targetHost, X509CertificateCollection localCertificates,
+ X509Certificate remoteCertificate, string[] acceptableIssuers)
+ {
+ return GetCertificate();
+ }
+
+ private static bool ClientCertValidator(object sender, X509Certificate certificate,
+ X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ {
+ return true;
+ }
+
+ private enum Transport
+ {
+ Tcp,
+ NamedPipe,
+ Http,
+ TcpTls,
+ }
+
+ private enum Buffering
+ {
+ None,
+ Buffered,
+ Framed,
+ }
+
+ private enum Protocol
+ {
+ Binary,
+ Compact,
+ Json,
+ Multiplexed
+ }
+
+ public class HttpServerSample
+ {
+ public void Run(CancellationToken cancellationToken)
+ {
+ var config = new ConfigurationBuilder()
+ .AddEnvironmentVariables(prefix: "ASPNETCORE_")
+ .Build();
+
+ var host = new WebHostBuilder()
+ .UseConfiguration(config)
+ .UseKestrel()
+ .UseUrls("http://localhost:9090")
+ .UseContentRoot(Directory.GetCurrentDirectory())
+ .UseStartup<Startup>()
+ .ConfigureLogging((ctx,logging) => ConfigureLogging(logging))
+ .Build();
+
+ Logger.LogTrace("test");
+ Logger.LogCritical("test");
+ host.RunAsync(cancellationToken).GetAwaiter().GetResult();
+ }
+
+ public class Startup
+ {
+ public Startup(IHostingEnvironment env)
+ {
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(env.ContentRootPath)
+ .AddEnvironmentVariables();
+
+ Configuration = builder.Build();
+ }
+
+ public IConfigurationRoot Configuration { get; }
+
+ // This method gets called by the runtime. Use this method to add services to the container.
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddTransient<Calculator.IAsync, CalculatorAsyncHandler>();
+ services.AddTransient<ITAsyncProcessor, Calculator.AsyncProcessor>();
+ services.AddTransient<THttpServerTransport, THttpServerTransport>();
+ }
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+ {
+ app.UseMiddleware<THttpServerTransport>();
+ }
+ }
+ }
+
+ public class CalculatorAsyncHandler : Calculator.IAsync
+ {
+ private readonly Dictionary<int, SharedStruct> _log = new Dictionary<int, SharedStruct>();
+
+ public CalculatorAsyncHandler()
+ {
+ }
+
+ public async Task<SharedStruct> getStructAsync(int key,
+ CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("GetStructAsync({0})", key);
+ return await Task.FromResult(_log[key]);
+ }
+
+ public async Task pingAsync(CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("PingAsync()");
+ await Task.CompletedTask;
+ }
+
+ public async Task<int> addAsync(int num1, int num2, CancellationToken cancellationToken)
+ {
+ Logger.LogInformation($"AddAsync({num1},{num2})");
+ return await Task.FromResult(num1 + num2);
+ }
+
+ public async Task<int> calculateAsync(int logid, Work w, CancellationToken cancellationToken)
+ {
+ Logger.LogInformation($"CalculateAsync({logid}, [{w.Op},{w.Num1},{w.Num2}])");
+
+ var val = 0;
+ switch (w.Op)
+ {
+ case Operation.ADD:
+ val = w.Num1 + w.Num2;
+ break;
+
+ case Operation.SUBTRACT:
+ val = w.Num1 - w.Num2;
+ break;
+
+ case Operation.MULTIPLY:
+ val = w.Num1 * w.Num2;
+ break;
+
+ case Operation.DIVIDE:
+ if (w.Num2 == 0)
+ {
+ var io = new InvalidOperation
+ {
+ WhatOp = (int) w.Op,
+ Why = "Cannot divide by 0"
+ };
+
+ throw io;
+ }
+ val = w.Num1 / w.Num2;
+ break;
+
+ default:
+ {
+ var io = new InvalidOperation
+ {
+ WhatOp = (int) w.Op,
+ Why = "Unknown operation"
+ };
+
+ throw io;
+ }
+ }
+
+ var entry = new SharedStruct
+ {
+ Key = logid,
+ Value = val.ToString()
+ };
+
+ _log[logid] = entry;
+
+ return await Task.FromResult(val);
+ }
+
+ public async Task zipAsync(CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("ZipAsync() with delay 100mc");
+ await Task.Delay(100, CancellationToken.None);
+ }
+ }
+
+ public class SharedServiceAsyncHandler : SharedService.IAsync
+ {
+ public async Task<SharedStruct> getStructAsync(int key, CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("GetStructAsync({0})", key);
+ return await Task.FromResult(new SharedStruct()
+ {
+ Key = key,
+ Value = "GetStructAsync"
+ });
+ }
+ }
+ }
+}
diff --git a/tutorial/netstd/Server/Properties/AssemblyInfo.cs b/tutorial/netstd/Server/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a044235
--- /dev/null
+++ b/tutorial/netstd/Server/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// 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.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("e210fc10-5aff-4b04-ac21-58afc7b74b0c")]
\ No newline at end of file
diff --git a/tutorial/netstd/Server/Properties/launchSettings.json b/tutorial/netstd/Server/Properties/launchSettings.json
new file mode 100644
index 0000000..78076ff
--- /dev/null
+++ b/tutorial/netstd/Server/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "Server": {
+ "commandName": "Project",
+ "commandLineArgs": "-p:multiplexed"
+ }
+ }
+}
\ No newline at end of file
diff --git a/tutorial/netstd/Server/Server.csproj b/tutorial/netstd/Server/Server.csproj
new file mode 100644
index 0000000..fbc2c03
--- /dev/null
+++ b/tutorial/netstd/Server/Server.csproj
@@ -0,0 +1,44 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+ <!--
+ 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.
+ -->
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ <AssemblyName>Server</AssemblyName>
+ <PackageId>Server</PackageId>
+ <OutputType>Exe</OutputType>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../Interfaces/Interfaces.csproj" />
+ <ProjectReference Include="../../../lib/netstd/Thrift/Thrift.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
+ <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="2.2.1" />
+ <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" />
+ </ItemGroup>
+
+</Project>
diff --git a/tutorial/netstd/Server/ThriftTest.pfx b/tutorial/netstd/Server/ThriftTest.pfx
new file mode 100644
index 0000000..f0ded28
--- /dev/null
+++ b/tutorial/netstd/Server/ThriftTest.pfx
Binary files differ
diff --git a/tutorial/netstd/Tutorial.sln b/tutorial/netstd/Tutorial.sln
new file mode 100644
index 0000000..84b2579
--- /dev/null
+++ b/tutorial/netstd/Tutorial.sln
@@ -0,0 +1,78 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26114.2
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", "..\..\lib\netstd\Thrift\Thrift.csproj", "{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Interfaces", "Interfaces\Interfaces.csproj", "{B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{E08F5B84-2B4A-4E09-82D1-E0715775CE5E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.Build.0 = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.Build.0 = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x64.Build.0 = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x86.Build.0 = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x64.ActiveCfg = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x64.Build.0 = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x86.ActiveCfg = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x86.Build.0 = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x64.Build.0 = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x86.Build.0 = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x64.ActiveCfg = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x64.Build.0 = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x86.ActiveCfg = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x86.Build.0 = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x64.Build.0 = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x86.Build.0 = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x64.ActiveCfg = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x64.Build.0 = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x86.ActiveCfg = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {070A5D1D-B29D-4603-999D-693DB444AD0D}
+ EndGlobalSection
+EndGlobal
diff --git a/tutorial/netstd/build.cmd b/tutorial/netstd/build.cmd
new file mode 100644
index 0000000..9b84ef2
--- /dev/null
+++ b/tutorial/netstd/build.cmd
@@ -0,0 +1,25 @@
+@echo off
+rem /*
+rem * Licensed to the Apache Software Foundation (ASF) under one
+rem * or more contributor license agreements. See the NOTICE file
+rem * distributed with this work for additional information
+rem * regarding copyright ownership. The ASF licenses this file
+rem * to you under the Apache License, Version 2.0 (the
+rem * "License"); you may not use this file except in compliance
+rem * with the License. You may obtain a copy of the License at
+rem *
+rem * http://www.apache.org/licenses/LICENSE-2.0
+rem *
+rem * Unless required by applicable law or agreed to in writing,
+rem * software distributed under the License is distributed on an
+rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem * KIND, either express or implied. See the License for the
+rem * specific language governing permissions and limitations
+rem * under the License.
+rem */
+setlocal
+
+dotnet --info
+dotnet build
+
+:eof
diff --git a/lib/cpp/thrift-qt.pc.in b/tutorial/netstd/build.sh
old mode 100755
new mode 100644
similarity index 77%
copy from lib/cpp/thrift-qt.pc.in
copy to tutorial/netstd/build.sh
index 5e60d84..c97e310
--- a/lib/cpp/thrift-qt.pc.in
+++ b/tutorial/netstd/build.sh
@@ -1,3 +1,5 @@
+#!/usr/bin/env bash
+
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -17,14 +19,8 @@
# under the License.
#
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
+#exit if any command fails
+set -e
-Name: Thrift
-Description: Thrift Qt API
-Version: @VERSION@
-Requires: thrift = @VERSION@
-Libs: -L${libdir} -lthriftqt
-Cflags: -I${includedir}
+dotnet --info
+dotnet build
diff --git a/tutorial/ocaml/_oasis b/tutorial/ocaml/_oasis
index 9dbb6a0..4a4f337 100644
--- a/tutorial/ocaml/_oasis
+++ b/tutorial/ocaml/_oasis
@@ -1,5 +1,5 @@
Name: tutorial
-Version: 0.12.1
+Version: 0.13.0
OASISFormat: 0.3
Synopsis: OCaml Tutorial example
Authors: Apache Thrift Developers <dev@thrift.apache.org>
diff --git a/tutorial/php/runserver.py b/tutorial/php/runserver.py
index 077daa1..8cc30fb 100755
--- a/tutorial/php/runserver.py
+++ b/tutorial/php/runserver.py
@@ -30,4 +30,5 @@
class Handler(CGIHTTPServer.CGIHTTPRequestHandler):
cgi_directories = ['/php']
+
BaseHTTPServer.HTTPServer(('', 8080), Handler).serve_forever()
diff --git a/tutorial/py.twisted/PythonClient.py b/tutorial/py.twisted/PythonClient.py
index 63dde7e..2976495 100755
--- a/tutorial/py.twisted/PythonClient.py
+++ b/tutorial/py.twisted/PythonClient.py
@@ -67,6 +67,7 @@
print(('Check log: %s' % (log.value)))
reactor.stop()
+
if __name__ == '__main__':
d = ClientCreator(reactor,
TTwisted.ThriftClientProtocol,
diff --git a/tutorial/py.twisted/PythonServer.py b/tutorial/py.twisted/PythonServer.py
index 1b0e2d5..034e4a3 100755
--- a/tutorial/py.twisted/PythonServer.py
+++ b/tutorial/py.twisted/PythonServer.py
@@ -85,6 +85,7 @@
def zip(self):
print('zip()')
+
if __name__ == '__main__':
handler = CalculatorHandler()
processor = Calculator.Processor(handler)
diff --git a/tutorial/rs/src/bin/tutorial_client.rs b/tutorial/rs/src/bin/tutorial_client.rs
index c80fafc..bfd81d4 100644
--- a/tutorial/rs/src/bin/tutorial_client.rs
+++ b/tutorial/rs/src/bin/tutorial_client.rs
@@ -75,7 +75,7 @@
println!("multiplied 7 and 8 and got {}", res);
// let's get the log for it
- let res = client.get_struct(32)?;
+ let res = client.get_struct(logid /* 32 */)?;
println!("got log {:?} for operation {}", res, logid);
// ok - let's be bad :(
diff --git a/tutorial/shared.thrift b/tutorial/shared.thrift
index f1685bd..5747f06 100644
--- a/tutorial/shared.thrift
+++ b/tutorial/shared.thrift
@@ -31,6 +31,8 @@
namespace php shared
namespace haxe shared
namespace netcore shared
+namespace netstd shared
+
struct SharedStruct {
1: i32 key
diff --git a/tutorial/tutorial.thrift b/tutorial/tutorial.thrift
index e027546..ea18b73 100644
--- a/tutorial/tutorial.thrift
+++ b/tutorial/tutorial.thrift
@@ -72,6 +72,7 @@
namespace perl tutorial
namespace haxe tutorial
namespace netcore tutorial
+namespace netstd tutorial
/**
* Thrift lets you do typedefs to get pretty names for your types. Standard